From 63c5df6aa73be0a5de83df995b0a3721fdf0ecbe Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Mon, 3 Feb 2020 23:05:46 -0400 Subject: [PATCH] Begin unification of Canvases and Images. --- src/modules/graphics/Canvas.cpp | 26 +----- src/modules/graphics/Canvas.h | 20 +---- src/modules/graphics/Graphics.cpp | 103 ++++++++++++----------- src/modules/graphics/Graphics.h | 44 +++++----- src/modules/graphics/Image.cpp | 36 ++++---- src/modules/graphics/Image.h | 8 +- src/modules/graphics/Texture.cpp | 24 ++++++ src/modules/graphics/Texture.h | 11 ++- src/modules/graphics/opengl/Canvas.cpp | 7 +- src/modules/graphics/opengl/Graphics.cpp | 79 +++++++++-------- src/modules/graphics/opengl/Graphics.h | 2 +- src/modules/graphics/opengl/Image.cpp | 20 +---- src/modules/graphics/opengl/OpenGL.cpp | 4 +- src/modules/graphics/wrap_Canvas.cpp | 18 ++-- src/modules/graphics/wrap_Graphics.cpp | 32 +++---- src/modules/graphics/wrap_Image.cpp | 2 +- 16 files changed, 211 insertions(+), 225 deletions(-) diff --git a/src/modules/graphics/Canvas.cpp b/src/modules/graphics/Canvas.cpp index 5c3ebe857..2866b0121 100644 --- a/src/modules/graphics/Canvas.cpp +++ b/src/modules/graphics/Canvas.cpp @@ -102,7 +102,7 @@ Canvas::~Canvas() { } -Canvas::MipmapMode Canvas::getMipmapMode() const +Texture::MipmapsMode Canvas::getMipmapsMode() const { return settings.mipmaps; } @@ -141,21 +141,6 @@ love::image::ImageData *Canvas::newImageData(love::image::Image *module, int sli return module->newImageData(r.w, r.h, dataformat); } -bool Canvas::getConstant(const char *in, MipmapMode &out) -{ - return mipmapModes.find(in, out); -} - -bool Canvas::getConstant(MipmapMode in, const char *&out) -{ - return mipmapModes.find(in, out); -} - -std::vector Canvas::getConstants(MipmapMode) -{ - return mipmapModes.getNames(); -} - bool Canvas::getConstant(const char *in, SettingType &out) { return settingTypes.find(in, out); @@ -178,15 +163,6 @@ std::vector Canvas::getConstants(SettingType) return settingTypes.getNames(); } -StringMap::Entry Canvas::mipmapEntries[] = -{ - { "none", MIPMAPS_NONE }, - { "manual", MIPMAPS_MANUAL }, - { "auto", MIPMAPS_AUTO }, -}; - -StringMap Canvas::mipmapModes(Canvas::mipmapEntries, sizeof(Canvas::mipmapEntries)); - StringMap::Entry Canvas::settingTypeEntries[] = { // Width / height / layers are currently omittted because they're separate diff --git a/src/modules/graphics/Canvas.h b/src/modules/graphics/Canvas.h index ac2a72e73..d683e9d5d 100644 --- a/src/modules/graphics/Canvas.h +++ b/src/modules/graphics/Canvas.h @@ -39,14 +39,6 @@ public: static love::Type type; - enum MipmapMode - { - MIPMAPS_NONE, - MIPMAPS_MANUAL, - MIPMAPS_AUTO, - MIPMAPS_MAX_ENUM - }; - enum SettingType { SETTING_WIDTH, @@ -66,7 +58,7 @@ public: int width = 1; int height = 1; int layers = 1; // depth for 3D textures - MipmapMode mipmaps = MIPMAPS_NONE; + MipmapsMode mipmaps = MIPMAPS_NONE; PixelFormat format = PIXELFORMAT_NORMAL; TextureType type = TEXTURE_2D; float dpiScale = 1.0f; @@ -77,14 +69,10 @@ public: Canvas(const Settings &settings); virtual ~Canvas(); - MipmapMode getMipmapMode() const; + MipmapsMode getMipmapsMode() const; virtual love::image::ImageData *newImageData(love::image::Image *module, int slice, int mipmap, const Rect &rect); - static bool getConstant(const char *in, MipmapMode &out); - static bool getConstant(MipmapMode in, const char *&out); - static std::vector getConstants(MipmapMode); - static bool getConstant(const char *in, SettingType &out); static bool getConstant(SettingType in, const char *&out); static const char *getConstant(SettingType in); @@ -96,8 +84,8 @@ protected: private: - static StringMap::Entry mipmapEntries[]; - static StringMap mipmapModes; + static StringMap::Entry mipmapEntries[]; + static StringMap mipmapModes; static StringMap::Entry settingTypeEntries[]; static StringMap settingTypes; diff --git a/src/modules/graphics/Graphics.cpp b/src/modules/graphics/Graphics.cpp index 5ae9493dd..c0a5a2f1f 100644 --- a/src/modules/graphics/Graphics.cpp +++ b/src/modules/graphics/Graphics.cpp @@ -116,7 +116,7 @@ Graphics::Graphics() , writingToStencil(false) , streamBufferState() , projectionMatrix() - , canvasSwitchCount(0) + , renderTargetSwitchCount(0) , drawCalls(0) , drawCallsBatched(0) , quadIndexBuffer(nullptr) @@ -335,8 +335,8 @@ int Graphics::getPixelHeight() const double Graphics::getCurrentDPIScale() const { const auto &rt = states.back().renderTargets.getFirstTarget(); - if (rt.canvas.get()) - return rt.canvas->getDPIScale(); + if (rt.texture.get()) + return rt.texture->getDPIScale(); return getScreenDPIScale(); } @@ -545,7 +545,7 @@ love::graphics::Shader *Graphics::getShader() const void Graphics::setCanvas(RenderTarget rt, uint32 temporaryRTFlags) { - if (rt.canvas == nullptr) + if (rt.texture == nullptr) return setCanvas(); RenderTargets rts; @@ -561,9 +561,9 @@ void Graphics::setCanvas(const RenderTargetsStrongRef &rts) targets.colors.reserve(rts.colors.size()); for (const auto &rt : rts.colors) - targets.colors.emplace_back(rt.canvas.get(), rt.slice, rt.mipmap); + targets.colors.emplace_back(rt.texture.get(), rt.slice, rt.mipmap); - targets.depthStencil = RenderTarget(rts.depthStencil.canvas, rts.depthStencil.slice, rts.depthStencil.mipmap); + targets.depthStencil = RenderTarget(rts.depthStencil.texture, rts.depthStencil.slice, rts.depthStencil.mipmap); targets.temporaryRTFlags = rts.temporaryRTFlags; return setCanvas(targets); @@ -575,9 +575,9 @@ void Graphics::setCanvas(const RenderTargets &rts) int ncanvases = (int) rts.colors.size(); RenderTarget firsttarget = rts.getFirstTarget(); - love::graphics::Canvas *firstcanvas = firsttarget.canvas; + Texture *firsttex = firsttarget.texture; - if (firstcanvas == nullptr) + if (firsttex == nullptr) return setCanvas(); const auto &prevRTs = state.renderTargets; @@ -612,29 +612,35 @@ void Graphics::setCanvas(const RenderTargets &rts) PixelFormat firstcolorformat = PIXELFORMAT_UNKNOWN; if (!rts.colors.empty()) - firstcolorformat = rts.colors[0].canvas->getPixelFormat(); + firstcolorformat = rts.colors[0].texture->getPixelFormat(); + + if (!firsttex->isRenderTarget()) + throw love::Exception("Texture must be created as a render target to be used in setCanvas."); if (isPixelFormatDepthStencil(firstcolorformat)) throw love::Exception("Depth/stencil format Canvases must be used with the 'depthstencil' field of the table passed into setCanvas."); - if (firsttarget.mipmap < 0 || firsttarget.mipmap >= firstcanvas->getMipmapCount()) + if (firsttarget.mipmap < 0 || firsttarget.mipmap >= firsttex->getMipmapCount()) throw love::Exception("Invalid mipmap level %d.", firsttarget.mipmap + 1); - if (!firstcanvas->isValidSlice(firsttarget.slice)) + if (!firsttex->isValidSlice(firsttarget.slice)) throw love::Exception("Invalid slice index: %d.", firsttarget.slice + 1); bool hasSRGBcanvas = firstcolorformat == PIXELFORMAT_sRGBA8_UNORM; - int pixelw = firstcanvas->getPixelWidth(firsttarget.mipmap); - int pixelh = firstcanvas->getPixelHeight(firsttarget.mipmap); - int reqmsaa = firstcanvas->getRequestedMSAA(); + int pixelw = firsttex->getPixelWidth(firsttarget.mipmap); + int pixelh = firsttex->getPixelHeight(firsttarget.mipmap); + int reqmsaa = firsttex->getRequestedMSAA(); for (int i = 1; i < ncanvases; i++) { - love::graphics::Canvas *c = rts.colors[i].canvas; + Texture *c = rts.colors[i].texture; PixelFormat format = c->getPixelFormat(); int mip = rts.colors[i].mipmap; int slice = rts.colors[i].slice; + if (!c->isRenderTarget()) + throw love::Exception("Texture must be created as a render target to be used in setCanvas."); + if (mip < 0 || mip >= c->getMipmapCount()) throw love::Exception("Invalid mipmap level %d.", mip + 1); @@ -657,20 +663,23 @@ void Graphics::setCanvas(const RenderTargets &rts) hasSRGBcanvas = true; } - if (rts.depthStencil.canvas != nullptr) + if (rts.depthStencil.texture != nullptr) { - love::graphics::Canvas *c = rts.depthStencil.canvas; + Texture *c = rts.depthStencil.texture; int mip = rts.depthStencil.mipmap; int slice = rts.depthStencil.slice; + if (!c->isRenderTarget()) + throw love::Exception("Texture must be created as a render target to be used in setCanvas."); + if (!isPixelFormatDepthStencil(c->getPixelFormat())) - throw love::Exception("Only depth/stencil format Canvases can be used with the 'depthstencil' field of the table passed into setCanvas."); + throw love::Exception("Only depth/stencil format Texture can be used with the 'depthstencil' field of the table passed into setCanvas."); if (c->getPixelWidth(mip) != pixelw || c->getPixelHeight(mip) != pixelh) - throw love::Exception("All canvases must have the same pixel dimensions."); + throw love::Exception("All Textures must have the same pixel dimensions."); - if (c->getRequestedMSAA() != firstcanvas->getRequestedMSAA()) - throw love::Exception("All Canvases must have the same MSAA value."); + if (c->getRequestedMSAA() != firsttex->getRequestedMSAA()) + throw love::Exception("All Textures must have the same MSAA value."); if (mip < 0 || mip >= c->getMipmapCount()) throw love::Exception("Invalid mipmap level %d.", mip + 1); @@ -679,12 +688,12 @@ void Graphics::setCanvas(const RenderTargets &rts) throw love::Exception("Invalid slice index: %d.", slice + 1); } - int w = firstcanvas->getWidth(firsttarget.mipmap); - int h = firstcanvas->getHeight(firsttarget.mipmap); + int w = firsttex->getWidth(firsttarget.mipmap); + int h = firsttex->getHeight(firsttarget.mipmap); flushStreamDraws(); - if (rts.depthStencil.canvas == nullptr && rts.temporaryRTFlags != 0) + if (rts.depthStencil.texture == nullptr && rts.temporaryRTFlags != 0) { bool wantsdepth = (rts.temporaryRTFlags & TEMPORARY_RT_DEPTH) != 0; bool wantsstencil = (rts.temporaryRTFlags & TEMPORARY_RT_STENCIL) != 0; @@ -703,7 +712,7 @@ void Graphics::setCanvas(const RenderTargets &rts) // we don't want to directly store it in the main graphics state. RenderTargets realRTs = rts; - realRTs.depthStencil.canvas = getTemporaryCanvas(dsformat, pixelw, pixelh, reqmsaa); + realRTs.depthStencil.texture = getTemporaryTexture(dsformat, pixelw, pixelh, reqmsaa); realRTs.depthStencil.slice = 0; setCanvasInternal(realRTs, w, h, pixelw, pixelh, hasSRGBcanvas); @@ -715,28 +724,28 @@ void Graphics::setCanvas(const RenderTargets &rts) refs.colors.reserve(rts.colors.size()); for (auto c : rts.colors) - refs.colors.emplace_back(c.canvas, c.slice, c.mipmap); + refs.colors.emplace_back(c.texture, c.slice, c.mipmap); - refs.depthStencil = RenderTargetStrongRef(rts.depthStencil.canvas, rts.depthStencil.slice); + refs.depthStencil = RenderTargetStrongRef(rts.depthStencil.texture, rts.depthStencil.slice); refs.temporaryRTFlags = rts.temporaryRTFlags; std::swap(state.renderTargets, refs); - canvasSwitchCount++; + renderTargetSwitchCount++; } void Graphics::setCanvas() { DisplayState &state = states.back(); - if (state.renderTargets.colors.empty() && state.renderTargets.depthStencil.canvas == nullptr) + if (state.renderTargets.colors.empty() && state.renderTargets.depthStencil.texture == nullptr) return; flushStreamDraws(); setCanvasInternal(RenderTargets(), width, height, pixelWidth, pixelHeight, isGammaCorrect()); state.renderTargets = RenderTargetsStrongRef(); - canvasSwitchCount++; + renderTargetSwitchCount++; } Graphics::RenderTargets Graphics::getCanvas() const @@ -747,9 +756,9 @@ Graphics::RenderTargets Graphics::getCanvas() const rts.colors.reserve(curRTs.colors.size()); for (const auto &rt : curRTs.colors) - rts.colors.emplace_back(rt.canvas.get(), rt.slice, rt.mipmap); + rts.colors.emplace_back(rt.texture.get(), rt.slice, rt.mipmap); - rts.depthStencil = RenderTarget(curRTs.depthStencil.canvas, curRTs.depthStencil.slice, curRTs.depthStencil.mipmap); + rts.depthStencil = RenderTarget(curRTs.depthStencil.texture, curRTs.depthStencil.slice, curRTs.depthStencil.mipmap); rts.temporaryRTFlags = curRTs.temporaryRTFlags; return rts; @@ -758,7 +767,7 @@ Graphics::RenderTargets Graphics::getCanvas() const bool Graphics::isCanvasActive() const { const auto &rts = states.back().renderTargets; - return !rts.colors.empty() || rts.depthStencil.canvas != nullptr; + return !rts.colors.empty() || rts.depthStencil.texture != nullptr; } bool Graphics::isRenderTargetActive(Texture *texture) const @@ -767,11 +776,11 @@ bool Graphics::isRenderTargetActive(Texture *texture) const for (const auto &rt : rts.colors) { - if (rt.canvas.get() == texture) + if (rt.texture.get() == texture) return true; } - if (rts.depthStencil.canvas.get() == texture) + if (rts.depthStencil.texture.get() == texture) return true; return false; @@ -783,33 +792,33 @@ bool Graphics::isRenderTargetActive(Texture *texture, int slice) const for (const auto &rt : rts.colors) { - if (rt.canvas.get() == texture && rt.slice == slice) + if (rt.texture.get() == texture && rt.slice == slice) return true; } - if (rts.depthStencil.canvas.get() == texture && rts.depthStencil.slice == slice) + if (rts.depthStencil.texture.get() == texture && rts.depthStencil.slice == slice) return true; return false; } -Canvas *Graphics::getTemporaryCanvas(PixelFormat format, int w, int h, int samples) +Texture *Graphics::getTemporaryTexture(PixelFormat format, int w, int h, int samples) { - love::graphics::Canvas *canvas = nullptr; + Texture *texture = nullptr; - for (TemporaryCanvas &temp : temporaryCanvases) + for (TemporaryTexture &temp : temporaryTextures) { - Canvas *c = temp.canvas; + Texture *c = temp.texture; if (c->getPixelFormat() == format && c->getPixelWidth() == w && c->getPixelHeight() == h && c->getRequestedMSAA() == samples) { - canvas = c; + texture = c; temp.framesSinceUse = 0; break; } } - if (canvas == nullptr) + if (texture == nullptr) { Canvas::Settings settings; settings.format = format; @@ -817,12 +826,12 @@ Canvas *Graphics::getTemporaryCanvas(PixelFormat format, int w, int h, int sampl settings.height = h; settings.msaa = samples; - canvas = newCanvas(settings); + texture = newCanvas(settings); - temporaryCanvases.emplace_back(canvas); + temporaryTextures.emplace_back(texture); } - return canvas; + return texture; } void Graphics::intersectScissor(const Rect &rect) @@ -1591,7 +1600,7 @@ Graphics::Stats Graphics::getStats() const if (streamBufferState.vertexCount > 0) stats.drawCalls++; - stats.canvasSwitches = canvasSwitchCount; + stats.renderTargetSwitches = renderTargetSwitchCount; stats.drawCallsBatched = drawCallsBatched; stats.textures = Texture::textureCount; stats.fonts = Font::fontCount; diff --git a/src/modules/graphics/Graphics.h b/src/modules/graphics/Graphics.h index cac7a6edc..cf4429e3b 100644 --- a/src/modules/graphics/Graphics.h +++ b/src/modules/graphics/Graphics.h @@ -200,7 +200,7 @@ public: { int drawCalls; int drawCallsBatched; - int canvasSwitches; + int renderTargetSwitches; int shaderSwitches; int textures; int fonts; @@ -315,53 +315,53 @@ public: struct RenderTarget { - Canvas *canvas; + Texture *texture; int slice; int mipmap; - RenderTarget(Canvas *canvas, int slice = 0, int mipmap = 0) - : canvas(canvas) + RenderTarget(Texture *texture, int slice = 0, int mipmap = 0) + : texture(texture) , slice(slice) , mipmap(mipmap) {} RenderTarget() - : canvas(nullptr) + : texture(nullptr) , slice(0) , mipmap(0) {} bool operator != (const RenderTarget &other) const { - return canvas != other.canvas || slice != other.slice || mipmap != other.mipmap; + return texture != other.texture || slice != other.slice || mipmap != other.mipmap; } bool operator != (const RenderTargetStrongRef &other) const { - return canvas != other.canvas.get() || slice != other.slice || mipmap != other.mipmap; + return texture != other.texture.get() || slice != other.slice || mipmap != other.mipmap; } }; struct RenderTargetStrongRef { - StrongRef canvas; + StrongRef texture; int slice = 0; int mipmap = 0; - RenderTargetStrongRef(Canvas *canvas, int slice = 0, int mipmap = 0) - : canvas(canvas) + RenderTargetStrongRef(Texture *texture, int slice = 0, int mipmap = 0) + : texture(texture) , slice(slice) , mipmap(mipmap) {} bool operator != (const RenderTargetStrongRef &other) const { - return canvas.get() != other.canvas.get() || slice != other.slice || mipmap != other.mipmap; + return texture.get() != other.texture.get() || slice != other.slice || mipmap != other.mipmap; } bool operator != (const RenderTarget &other) const { - return canvas.get() != other.canvas || slice != other.slice || mipmap != other.mipmap; + return texture.get() != other.texture || slice != other.slice || mipmap != other.mipmap; } }; @@ -619,12 +619,12 @@ public: const BlendState &getBlendState() const; /** - * Sets the default sampler state for images, canvases, and fonts. + * Sets the default sampler state for textures, videos, and fonts. **/ void setDefaultSamplerState(const SamplerState &s); /** - * Gets the default sampler state for images, canvases, and fonts. + * Gets the default sampler state for textures, videos, and fonts. **/ const SamplerState &getDefaultSamplerState() const; @@ -939,13 +939,13 @@ protected: } }; - struct TemporaryCanvas + struct TemporaryTexture { - Canvas *canvas; + Texture *texture; int framesSinceUse; - TemporaryCanvas(Canvas *c) - : canvas(c) + TemporaryTexture(Texture *tex) + : texture(tex) , framesSinceUse(0) {} }; @@ -961,7 +961,7 @@ protected: void createQuadIndexBuffer(); - Canvas *getTemporaryCanvas(PixelFormat format, int w, int h, int samples); + Texture *getTemporaryTexture(PixelFormat format, int w, int h, int samples); void restoreState(const DisplayState &s); void restoreStateChecked(const DisplayState &s); @@ -994,9 +994,9 @@ protected: std::vector states; std::vector stackTypeStack; - std::vector temporaryCanvases; + std::vector temporaryTextures; - int canvasSwitchCount; + int renderTargetSwitchCount; int drawCalls; int drawCallsBatched; @@ -1007,7 +1007,7 @@ protected: Deprecations deprecations; static const size_t MAX_USER_STACK_DEPTH = 128; - static const int MAX_TEMPORARY_CANVAS_UNUSED_FRAMES = 16; + static const int MAX_TEMPORARY_TEXTURE_UNUSED_FRAMES = 16; private: diff --git a/src/modules/graphics/Image.cpp b/src/modules/graphics/Image.cpp index 99d89d98e..f7fd92529 100644 --- a/src/modules/graphics/Image.cpp +++ b/src/modules/graphics/Image.cpp @@ -31,20 +31,17 @@ namespace graphics love::Type Image::type("Image", &Texture::type); -Image::Image(const Slices &data, const Settings &settings, bool validatedata) - : Texture(data.getTextureType()) +Image::Image(TextureType textype, const Settings &settings) + : Texture(textype) , settings(settings) - , mipmapsType(settings.mipmaps ? MIPMAPS_GENERATED : MIPMAPS_NONE) , usingDefaultTexture(false) { renderTarget = false; sRGB = isGammaCorrect() && !settings.linear; - if (validatedata && data.validate() && data.getMipmapCount() > 1) - mipmapsType = MIPMAPS_DATA; } Image::Image(TextureType textype, PixelFormat format, int width, int height, int slices, const Settings &settings) - : Image(Slices(textype), settings, false) + : Image(textype, settings) { if (isPixelFormatCompressed(format)) throw love::Exception("This constructor is only supported for non-compressed pixel formats."); @@ -54,26 +51,30 @@ Image::Image(TextureType textype, PixelFormat format, int width, int height, int else if (textype == TEXTURE_VOLUME) depth = slices; - init(format, width, height, settings); + init(format, width, height, 1, settings); } Image::Image(const Slices &slices, const Settings &settings) - : Image(slices, settings, true) + : Image(slices.getTextureType(), settings) { + int dataMipmaps = 1; + if (slices.validate() && slices.getMipmapCount() > 1) + dataMipmaps = slices.getMipmapCount(); + if (texType == TEXTURE_2D_ARRAY) this->layers = slices.getSliceCount(); else if (texType == TEXTURE_VOLUME) this->depth = slices.getSliceCount(); love::image::ImageDataBase *slice = slices.get(0, 0); - init(slice->getFormat(), slice->getWidth(), slice->getHeight(), settings); + init(slice->getFormat(), slice->getWidth(), slice->getHeight(), dataMipmaps, settings); } Image::~Image() { } -void Image::init(PixelFormat fmt, int w, int h, const Settings &settings) +void Image::init(PixelFormat fmt, int w, int h, int dataMipmaps, const Settings &settings) { Graphics *gfx = Module::getInstance(Module::M_GRAPHICS); if (gfx != nullptr && !gfx->isPixelFormatSupported(fmt, renderTarget, readable, sRGB)) @@ -96,10 +97,10 @@ void Image::init(PixelFormat fmt, int w, int h, const Settings &settings) format = fmt; - if (isCompressed() && mipmapsType == MIPMAPS_GENERATED) - mipmapsType = MIPMAPS_NONE; - - mipmapCount = mipmapsType == MIPMAPS_NONE ? 1 : getTotalMipmapCount(w, h, depth); + if (!settings.mipmaps || (isCompressed() && dataMipmaps <= 1)) + mipmapCount = 1; + else + mipmapCount = getTotalMipmapCount(w, h, depth); initQuad(); } @@ -125,7 +126,7 @@ void Image::replacePixels(love::image::ImageDataBase *d, int slice, int mipmap, if (d->getFormat() != getPixelFormat()) throw love::Exception("Pixel formats must match."); - if (mipmap < 0 || (mipmapsType != MIPMAPS_DATA && mipmap > 0) || mipmap >= getMipmapCount()) + if (mipmap < 0 || mipmap >= getMipmapCount()) throw love::Exception("Invalid image mipmap index %d.", mipmap + 1); if (slice < 0 || (texType == TEXTURE_CUBE && slice >= 6) @@ -168,11 +169,6 @@ void Image::replacePixels(const void *data, size_t size, int slice, int mipmap, generateMipmaps(); } -Image::MipmapsType Image::getMipmapsType() const -{ - return mipmapsType; -} - bool Image::getConstant(const char *in, SettingType &out) { return settingTypes.find(in, out); diff --git a/src/modules/graphics/Image.h b/src/modules/graphics/Image.h index 4341e6308..1fd9fdd07 100644 --- a/src/modules/graphics/Image.h +++ b/src/modules/graphics/Image.h @@ -57,8 +57,6 @@ public: void replacePixels(love::image::ImageDataBase *d, int slice, int mipmap, int x, int y, bool reloadmipmaps); void replacePixels(const void *data, size_t size, int slice, int mipmap, const Rect &rect, bool reloadmipmaps); - MipmapsType getMipmapsType() const; - static bool getConstant(const char *in, SettingType &out); static bool getConstant(SettingType in, const char *&out); static const char *getConstant(SettingType in); @@ -75,17 +73,15 @@ protected: // The settings used to initialize this Image. Settings settings; - MipmapsType mipmapsType; - // True if the image wasn't able to be properly created and it had to fall // back to a default texture. bool usingDefaultTexture; private: - Image(const Slices &data, const Settings &settings, bool validatedata); + Image(TextureType textype, const Settings &settings); - void init(PixelFormat fmt, int w, int h, const Settings &settings); + void init(PixelFormat fmt, int w, int h, int dataMipmaps, const Settings &settings); static StringMap::Entry settingTypeEntries[]; static StringMap settingTypes; diff --git a/src/modules/graphics/Texture.cpp b/src/modules/graphics/Texture.cpp index 35b846258..bf380e32d 100644 --- a/src/modules/graphics/Texture.cpp +++ b/src/modules/graphics/Texture.cpp @@ -680,5 +680,29 @@ StringMap::Entry Texture::texTypeEntries[] = StringMap Texture::texTypes(Texture::texTypeEntries, sizeof(Texture::texTypeEntries)); +static StringMap::Entry mipmapEntries[] = +{ + { "none", Texture::MIPMAPS_NONE }, + { "manual", Texture::MIPMAPS_MANUAL }, + { "auto", Texture::MIPMAPS_AUTO }, +}; + +static StringMap mipmapModes(mipmapEntries, sizeof(mipmapEntries)); + +bool Texture::getConstant(const char *in, MipmapsMode &out) +{ + return mipmapModes.find(in, out); +} + +bool Texture::getConstant(MipmapsMode in, const char *&out) +{ + return mipmapModes.find(in, out); +} + +std::vector Texture::getConstants(MipmapsMode) +{ + return mipmapModes.getNames(); +} + } // graphics } // love diff --git a/src/modules/graphics/Texture.h b/src/modules/graphics/Texture.h index 1ab277632..011d8a04f 100644 --- a/src/modules/graphics/Texture.h +++ b/src/modules/graphics/Texture.h @@ -128,11 +128,12 @@ public: static love::Type type; static int textureCount; - enum MipmapsType + enum MipmapsMode { MIPMAPS_NONE, - MIPMAPS_DATA, - MIPMAPS_GENERATED, + MIPMAPS_MANUAL, + MIPMAPS_AUTO, + MIPMAPS_MAX_ENUM }; struct Slices @@ -222,6 +223,10 @@ public: static bool getConstant(TextureType in, const char *&out); static std::vector getConstants(TextureType); + static bool getConstant(const char *in, MipmapsMode &out); + static bool getConstant(MipmapsMode in, const char *&out); + static std::vector getConstants(MipmapsMode); + protected: void initQuad(); diff --git a/src/modules/graphics/opengl/Canvas.cpp b/src/modules/graphics/opengl/Canvas.cpp index 7ee5faf3e..0a20ed94a 100644 --- a/src/modules/graphics/opengl/Canvas.cpp +++ b/src/modules/graphics/opengl/Canvas.cpp @@ -373,8 +373,11 @@ love::image::ImageData *Canvas::newImageData(love::image::Image *module, int sli void Canvas::generateMipmaps() { - if (getMipmapCount() == 1 || getMipmapMode() == MIPMAPS_NONE) - throw love::Exception("generateMipmaps can only be called on a Canvas which was created with mipmaps enabled."); + if (getMipmapCount() == 1 || getMipmapsMode() == MIPMAPS_NONE) + throw love::Exception("generateMipmaps can only be called on a Texture which was created with mipmaps enabled."); + + if (isPixelFormatCompressed(format)) + throw love::Exception("generateMipmaps cannot be called on a compressed Texture."); gl.bindTextureToUnit(this, 0, false); diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index 0b961c0ba..f020e28ec 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -234,7 +234,7 @@ bool Graphics::setMode(int width, int height, int pixelwidth, int pixelheight, b // Set whether drawing converts input from linear -> sRGB colorspace. if (GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_sRGB || GLAD_EXT_framebuffer_sRGB - || GLAD_ES_VERSION_3_0 || GLAD_EXT_sRGB) + || GLAD_ES_VERSION_3_0) { if (GLAD_VERSION_1_0 || GLAD_EXT_sRGB_write_control) gl.setEnableState(OpenGL::ENABLE_FRAMEBUFFER_SRGB, isGammaCorrect()); @@ -312,11 +312,11 @@ void Graphics::unSetMode() for (const auto &pair : framebufferObjects) gl.deleteFramebuffer(pair.second); - for (auto temp : temporaryCanvases) - temp.canvas->release(); + for (auto temp : temporaryTextures) + temp.texture->release(); framebufferObjects.clear(); - temporaryCanvases.clear(); + temporaryTextures.clear(); if (mainVAO != 0) { @@ -518,7 +518,7 @@ void Graphics::setCanvasInternal(const RenderTargets &rts, int w, int h, int pix flushStreamDraws(); endPass(); - bool iswindow = rts.getFirstTarget().canvas == nullptr; + bool iswindow = rts.getFirstTarget().texture == nullptr; vertex::Winding vertexwinding = state.winding; if (iswindow) @@ -560,7 +560,7 @@ void Graphics::setCanvasInternal(const RenderTargets &rts, int w, int h, int pix void Graphics::endPass() { auto &rts = states.back().renderTargets; - love::graphics::Canvas *depthstencil = rts.depthStencil.canvas.get(); + love::graphics::Texture *depthstencil = rts.depthStencil.texture.get(); // Discard the depth/stencil buffer if we're using an internal cached one. if (depthstencil == nullptr && (rts.temporaryRTFlags & (TEMPORARY_RT_DEPTH | TEMPORARY_RT_STENCIL)) != 0) @@ -568,15 +568,16 @@ void Graphics::endPass() // Resolve MSAA buffers. MSAA is only supported for 2D render targets so we // don't have to worry about resolving to slices. - if (rts.colors.size() > 0 && rts.colors[0].canvas->getMSAA() > 1) + if (rts.colors.size() > 0 && rts.colors[0].texture->getMSAA() > 1) { int mip = rts.colors[0].mipmap; - int w = rts.colors[0].canvas->getPixelWidth(mip); - int h = rts.colors[0].canvas->getPixelHeight(mip); + int w = rts.colors[0].texture->getPixelWidth(mip); + int h = rts.colors[0].texture->getPixelHeight(mip); for (int i = 0; i < (int) rts.colors.size(); i++) { - Canvas *c = (Canvas *) rts.colors[i].canvas.get(); + // FIXME + Canvas *c = (Canvas *) rts.colors[i].texture.get(); if (!c->isReadable()) continue; @@ -619,13 +620,14 @@ void Graphics::endPass() for (const auto &rt : rts.colors) { - if (rt.canvas->getMipmapMode() == Canvas::MIPMAPS_AUTO && rt.mipmap == 0) - rt.canvas->generateMipmaps(); + // TODO +// if (rt.texture->getMipmapMode() == Canvas::MIPMAPS_AUTO && rt.mipmap == 0) +// rt.texture->generateMipmaps(); } - int dsmipmap = rts.depthStencil.mipmap; - if (depthstencil != nullptr && depthstencil->getMipmapMode() == Canvas::MIPMAPS_AUTO && dsmipmap == 0) - depthstencil->generateMipmaps(); +// int dsmipmap = rts.depthStencil.mipmap; +// if (depthstencil != nullptr && depthstencil->getMipmapMode() == Canvas::MIPMAPS_AUTO && dsmipmap == 0) +// depthstencil->generateMipmaps(); } void Graphics::clear(OptionalColorf c, OptionalInt stencil, OptionalDouble depth) @@ -818,25 +820,28 @@ void Graphics::discard(OpenGL::FramebufferTarget target, const std::vector glDiscardFramebufferEXT(gltarget, (GLint) attachments.size(), &attachments[0]); } -void Graphics::cleanupCanvas(Canvas *canvas) +void Graphics::cleanupCanvas(Canvas *texture) { + if (!texture->isRenderTarget()) + return; + for (auto it = framebufferObjects.begin(); it != framebufferObjects.end(); /**/) { - bool hascanvas = false; + bool hastexture = false; const auto &rts = it->first; for (const RenderTarget &rt : rts.colors) { - if (rt.canvas == canvas) + if (rt.texture == texture) { - hascanvas = true; + hastexture = true; break; } } - hascanvas = hascanvas || rts.depthStencil.canvas == canvas; + hastexture = hastexture || rts.depthStencil.texture == texture; - if (hascanvas) + if (hastexture) { if (isCreated()) gl.deleteFramebuffer(it->second); @@ -857,8 +862,8 @@ void Graphics::bindCachedFBO(const RenderTargets &targets) } else { - int msaa = targets.getFirstTarget().canvas->getMSAA(); - bool hasDS = targets.depthStencil.canvas != nullptr; + int msaa = targets.getFirstTarget().texture->getMSAA(); + bool hasDS = targets.depthStencil.texture != nullptr; glGenFramebuffers(1, &fbo); gl.bindFramebuffer(OpenGL::FRAMEBUFFER_ALL, fbo); @@ -868,9 +873,9 @@ void Graphics::bindCachedFBO(const RenderTargets &targets) auto attachCanvas = [&](const RenderTarget &rt) { - bool renderbuffer = msaa > 1 || !rt.canvas->isReadable(); + bool renderbuffer = msaa > 1 || !rt.texture->isReadable(); bool srgb = false; - OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(rt.canvas->getPixelFormat(), renderbuffer, srgb); + OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(rt.texture->getPixelFormat(), renderbuffer, srgb); if (fmt.framebufferAttachments[0] == GL_COLOR_ATTACHMENT0) { @@ -879,7 +884,7 @@ void Graphics::bindCachedFBO(const RenderTargets &targets) ncolortargets++; } - GLuint handle = (GLuint) rt.canvas->getRenderTargetHandle(); + GLuint handle = (GLuint) rt.texture->getRenderTargetHandle(); for (GLenum attachment : fmt.framebufferAttachments) { @@ -889,7 +894,7 @@ void Graphics::bindCachedFBO(const RenderTargets &targets) glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, handle); else { - TextureType textype = rt.canvas->getTextureType(); + TextureType textype = rt.texture->getTextureType(); int layer = textype == TEXTURE_CUBE ? 0 : rt.slice; int face = textype == TEXTURE_CUBE ? rt.slice : 0; @@ -1056,20 +1061,20 @@ void Graphics::present(void *screenshotCallbackData) // Reset the per-frame stat counts. drawCalls = 0; gl.stats.shaderSwitches = 0; - canvasSwitchCount = 0; + renderTargetSwitchCount = 0; drawCallsBatched = 0; - // This assumes temporary canvases will only be used within a render pass. - for (int i = (int) temporaryCanvases.size() - 1; i >= 0; i--) + // This assumes temporary textures will only be used within a render pass. + for (int i = (int) temporaryTextures.size() - 1; i >= 0; i--) { - if (temporaryCanvases[i].framesSinceUse >= MAX_TEMPORARY_CANVAS_UNUSED_FRAMES) + if (temporaryTextures[i].framesSinceUse >= MAX_TEMPORARY_TEXTURE_UNUSED_FRAMES) { - temporaryCanvases[i].canvas->release(); - temporaryCanvases[i] = temporaryCanvases.back(); - temporaryCanvases.pop_back(); + temporaryTextures[i].texture->release(); + temporaryTextures[i] = temporaryTextures.back(); + temporaryTextures.pop_back(); } else - temporaryCanvases[i].framesSinceUse++; + temporaryTextures[i].framesSinceUse++; } } @@ -1111,11 +1116,11 @@ void Graphics::setScissor() void Graphics::drawToStencilBuffer(StencilAction action, int value) { const auto &rts = states.back().renderTargets; - love::graphics::Canvas *dscanvas = rts.depthStencil.canvas.get(); + love::graphics::Texture *dstexture = rts.depthStencil.texture.get(); if (!isCanvasActive() && !windowHasStencil) throw love::Exception("The window must have stenciling enabled to draw to the main screen's stencil buffer."); - else if (isCanvasActive() && (rts.temporaryRTFlags & TEMPORARY_RT_STENCIL) == 0 && (dscanvas == nullptr || !isPixelFormatStencil(dscanvas->getPixelFormat()))) + else if (isCanvasActive() && (rts.temporaryRTFlags & TEMPORARY_RT_STENCIL) == 0 && (dstexture == nullptr || !isPixelFormatStencil(dstexture->getPixelFormat()))) throw love::Exception("Drawing to the stencil buffer with a Canvas active requires either stencil=true or a custom stencil-type Canvas to be used, in setCanvas."); flushStreamDraws(); diff --git a/src/modules/graphics/opengl/Graphics.h b/src/modules/graphics/opengl/Graphics.h index 837390585..3a711d2c1 100644 --- a/src/modules/graphics/opengl/Graphics.h +++ b/src/modules/graphics/opengl/Graphics.h @@ -126,7 +126,7 @@ private: for (size_t i = 0; i < rts.colors.size(); i++) hashtargets[hashcount++] = rts.colors[i]; - if (rts.depthStencil.canvas != nullptr) + if (rts.depthStencil.texture != nullptr) hashtargets[hashcount++] = rts.depthStencil; else if (rts.temporaryRTFlags != 0) hashtargets[hashcount++] = RenderTarget(nullptr, -1, rts.temporaryRTFlags); diff --git a/src/modules/graphics/opengl/Image.cpp b/src/modules/graphics/opengl/Image.cpp index a724b003b..95750aad5 100644 --- a/src/modules/graphics/opengl/Image.cpp +++ b/src/modules/graphics/opengl/Image.cpp @@ -148,7 +148,7 @@ void Image::loadData() d = std::max(d / 2, 1); } - if (mipmapsType == MIPMAPS_GENERATED) + if (getMipmapCount() > 1 && slices.getMipmapCount() <= 1) generateMipmaps(); } @@ -200,22 +200,11 @@ bool Image::loadVolatile() OpenGL::TempDebugGroup debuggroup("Image load"); - if (!isCompressed()) - { - // GL_EXT_sRGB doesn't support glGenerateMipmap for sRGB textures. - if (sRGB && (GLAD_ES_VERSION_2_0 && GLAD_EXT_sRGB && !GLAD_ES_VERSION_3_0) - && mipmapsType != MIPMAPS_DATA) - { - mipmapsType = MIPMAPS_NONE; - samplerState.mipmapFilter = SamplerState::MIPMAP_FILTER_NONE; - } - } - // NPOT textures don't support mipmapping without full NPOT support. if ((GLAD_ES_VERSION_2_0 && !(GLAD_ES_VERSION_3_0 || GLAD_OES_texture_npot)) && (pixelWidth != nextP2(pixelWidth) || pixelHeight != nextP2(pixelHeight))) { - mipmapsType = MIPMAPS_NONE; + mipmapCount = 1; samplerState.mipmapFilter = SamplerState::MIPMAP_FILTER_NONE; } @@ -231,11 +220,6 @@ bool Image::loadVolatile() setSamplerState(samplerState); - GLenum gltextype = OpenGL::getGLTextureType(texType); - - if (mipmapsType == MIPMAPS_NONE && (GLAD_ES_VERSION_3_0 || GLAD_VERSION_1_0)) - glTexParameteri(gltextype, GL_TEXTURE_MAX_LEVEL, 0); - while (glGetError() != GL_NO_ERROR); // Clear errors. try diff --git a/src/modules/graphics/opengl/OpenGL.cpp b/src/modules/graphics/opengl/OpenGL.cpp index 31b5a8d85..984140633 100644 --- a/src/modules/graphics/opengl/OpenGL.cpp +++ b/src/modules/graphics/opengl/OpenGL.cpp @@ -1794,10 +1794,10 @@ bool OpenGL::isPixelFormatSupported(PixelFormat pixelformat, bool rendertarget, && (GLAD_VERSION_2_1 || GLAD_EXT_texture_sRGB)); } else - return GLAD_ES_VERSION_3_0 || GLAD_EXT_sRGB; + return GLAD_ES_VERSION_3_0; } else - return GLAD_ES_VERSION_3_0 || GLAD_EXT_sRGB || GLAD_VERSION_2_1 || GLAD_EXT_texture_sRGB; + return GLAD_ES_VERSION_3_0 || GLAD_VERSION_2_1 || GLAD_EXT_texture_sRGB; case PIXELFORMAT_R16_UNORM: case PIXELFORMAT_RG16_UNORM: return GLAD_VERSION_3_0 diff --git a/src/modules/graphics/wrap_Canvas.cpp b/src/modules/graphics/wrap_Canvas.cpp index 5394d7c82..ee2b3be24 100644 --- a/src/modules/graphics/wrap_Canvas.cpp +++ b/src/modules/graphics/wrap_Canvas.cpp @@ -37,7 +37,7 @@ int w_Canvas_renderTo(lua_State *L) int startidx = 2; - if (rt.canvas->getTextureType() != TEXTURE_2D) + if (rt.texture->getTextureType() != TEXTURE_2D) { rt.slice = (int) luaL_checkinteger(L, 2) - 1; startidx++; @@ -53,10 +53,10 @@ int w_Canvas_renderTo(lua_State *L) Graphics::RenderTargets oldtargets = graphics->getCanvas(); for (auto c : oldtargets.colors) - c.canvas->retain(); + c.texture->retain(); - if (oldtargets.depthStencil.canvas != nullptr) - oldtargets.depthStencil.canvas->retain(); + if (oldtargets.depthStencil.texture != nullptr) + oldtargets.depthStencil.texture->retain(); luax_catchexcept(L, [&](){ graphics->setCanvas(rt, false); }); @@ -66,10 +66,10 @@ int w_Canvas_renderTo(lua_State *L) graphics->setCanvas(oldtargets); for (auto c : oldtargets.colors) - c.canvas->release(); + c.texture->release(); - if (oldtargets.depthStencil.canvas != nullptr) - oldtargets.depthStencil.canvas->release(); + if (oldtargets.depthStencil.texture != nullptr) + oldtargets.depthStencil.texture->release(); if (status != 0) return lua_error(L); @@ -119,8 +119,8 @@ int w_Canvas_getMipmapMode(lua_State *L) { Canvas *c = luax_checkcanvas(L, 1); const char *str; - if (!Canvas::getConstant(c->getMipmapMode(), str)) - return luax_enumerror(L, "mipmap mode", Canvas::getConstants(Canvas::MIPMAPS_MAX_ENUM), str); + if (!Texture::getConstant(c->getMipmapsMode(), str)) + return luax_enumerror(L, "mipmap mode", Texture::getConstants(Texture::MIPMAPS_MAX_ENUM), str); lua_pushstring(L, str); return 1; diff --git a/src/modules/graphics/wrap_Graphics.cpp b/src/modules/graphics/wrap_Graphics.cpp index e15629d4a..4b11756d5 100644 --- a/src/modules/graphics/wrap_Graphics.cpp +++ b/src/modules/graphics/wrap_Graphics.cpp @@ -252,7 +252,7 @@ static Graphics::RenderTarget checkRenderTarget(lua_State *L, int idx) Graphics::RenderTarget target(luax_checkcanvas(L, -1), 0); lua_pop(L, 1); - TextureType type = target.canvas->getTextureType(); + TextureType type = target.texture->getTextureType(); if (type == TEXTURE_2D_ARRAY || type == TEXTURE_VOLUME) target.slice = luax_checkintflag(L, idx, "layer") - 1; else if (type == TEXTURE_CUBE) @@ -294,7 +294,7 @@ int w_setCanvas(lua_State *L) { targets.colors.emplace_back(luax_checkcanvas(L, -1), 0); - if (targets.colors.back().canvas->getTextureType() != TEXTURE_2D) + if (targets.colors.back().texture->getTextureType() != TEXTURE_2D) return luaL_error(L, "Non-2D canvases must use the table-of-tables variant of setCanvas."); } @@ -311,13 +311,13 @@ int w_setCanvas(lua_State *L) else if (dstype == LUA_TBOOLEAN) targets.temporaryRTFlags |= luax_toboolean(L, -1) ? (tempdepthflag | tempstencilflag) : 0; else if (dstype != LUA_TNONE && dstype != LUA_TNIL) - targets.depthStencil.canvas = luax_checkcanvas(L, -1); + targets.depthStencil.texture = luax_checkcanvas(L, -1); lua_pop(L, 1); - if (targets.depthStencil.canvas == nullptr && (targets.temporaryRTFlags & tempdepthflag) == 0) + if (targets.depthStencil.texture == nullptr && (targets.temporaryRTFlags & tempdepthflag) == 0) targets.temporaryRTFlags |= luax_boolflag(L, 1, "depth", false) ? tempdepthflag : 0; - if (targets.depthStencil.canvas == nullptr && (targets.temporaryRTFlags & tempstencilflag) == 0) + if (targets.depthStencil.texture == nullptr && (targets.temporaryRTFlags & tempstencilflag) == 0) targets.temporaryRTFlags |= luax_boolflag(L, 1, "stencil", false) ? tempstencilflag : 0; } else @@ -325,7 +325,7 @@ int w_setCanvas(lua_State *L) for (int i = 1; i <= lua_gettop(L); i++) { Graphics::RenderTarget target(luax_checkcanvas(L, i), 0); - TextureType type = target.canvas->getTextureType(); + TextureType type = target.texture->getTextureType(); if (i == 1 && type != TEXTURE_2D) { @@ -348,7 +348,7 @@ int w_setCanvas(lua_State *L) } luax_catchexcept(L, [&]() { - if (targets.getFirstTarget().canvas != nullptr) + if (targets.getFirstTarget().texture != nullptr) instance()->setCanvas(targets); else instance()->setCanvas(); @@ -361,10 +361,10 @@ static void pushRenderTarget(lua_State *L, const Graphics::RenderTarget &rt) { lua_createtable(L, 1, 2); - luax_pushtype(L, rt.canvas); + luax_pushtype(L, rt.texture); lua_rawseti(L, -2, 1); - TextureType type = rt.canvas->getTextureType(); + TextureType type = rt.texture->getTextureType(); if (type == TEXTURE_2D_ARRAY || type == TEXTURE_VOLUME) { @@ -392,13 +392,13 @@ int w_getCanvas(lua_State *L) return 1; } - bool shouldUseTablesVariant = targets.depthStencil.canvas != nullptr; + bool shouldUseTablesVariant = targets.depthStencil.texture != nullptr; if (!shouldUseTablesVariant) { for (const auto &rt : targets.colors) { - if (rt.mipmap != 0 || rt.canvas->getTextureType() != TEXTURE_2D) + if (rt.mipmap != 0 || rt.texture->getTextureType() != TEXTURE_2D) { shouldUseTablesVariant = true; break; @@ -416,7 +416,7 @@ int w_getCanvas(lua_State *L) lua_rawseti(L, -2, i + 1); } - if (targets.depthStencil.canvas != nullptr) + if (targets.depthStencil.texture != nullptr) { pushRenderTarget(L, targets.depthStencil); lua_setfield(L, -2, "depthstencil"); @@ -427,7 +427,7 @@ int w_getCanvas(lua_State *L) else { for (const auto &rt : targets.colors) - luax_pushtype(L, rt.canvas); + luax_pushtype(L, rt.texture); return ntargets; } @@ -1240,8 +1240,8 @@ int w_newCanvas(lua_State *L) if (!lua_isnoneornil(L, -1)) { const char *str = luaL_checkstring(L, -1); - if (!Canvas::getConstant(str, settings.mipmaps)) - return luax_enumerror(L, "Canvas mipmap mode", Canvas::getConstants(settings.mipmaps), str); + if (!Texture::getConstant(str, settings.mipmaps)) + return luax_enumerror(L, "Texture mipmap mode", Texture::getConstants(settings.mipmaps), str); } lua_pop(L, 1); } @@ -2388,7 +2388,7 @@ int w_getStats(lua_State *L) lua_pushinteger(L, stats.drawCallsBatched); lua_setfield(L, -2, "drawcallsbatched"); - lua_pushinteger(L, stats.canvasSwitches); + lua_pushinteger(L, stats.renderTargetSwitches); lua_setfield(L, -2, "canvasswitches"); lua_pushinteger(L, stats.shaderSwitches); diff --git a/src/modules/graphics/wrap_Image.cpp b/src/modules/graphics/wrap_Image.cpp index db04b5b42..a58105438 100644 --- a/src/modules/graphics/wrap_Image.cpp +++ b/src/modules/graphics/wrap_Image.cpp @@ -40,7 +40,7 @@ int w_Image_replacePixels(lua_State *L) int mipmap = 0; int x = 0; int y = 0; - bool reloadmipmaps = i->getMipmapsType() == Image::MIPMAPS_GENERATED; + bool reloadmipmaps = false; // TODO i->getMipmapsSource() == Texture::MIPMAPS_SOURCE_GENERATED; if (i->getTextureType() != TEXTURE_2D) slice = (int) luaL_checkinteger(L, 3) - 1;