mirror of
https://github.com/love2d/love.git
synced 2026-08-15 15:51:12 +02:00
Remove graphics::Canvas and graphics::Image
This commit is contained in:
@@ -1,144 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2020 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
**/
|
||||
|
||||
#include "Canvas.h"
|
||||
#include "Graphics.h"
|
||||
|
||||
namespace love
|
||||
{
|
||||
namespace graphics
|
||||
{
|
||||
|
||||
love::Type Canvas::type("Canvas", &Texture::type);
|
||||
|
||||
Canvas::Canvas(const Settings &settings)
|
||||
: Texture(settings.type)
|
||||
{
|
||||
this->settings = settings;
|
||||
|
||||
renderTarget = true;
|
||||
sRGB = false;
|
||||
requestedMSAA = settings.msaa;
|
||||
|
||||
mipmapsMode = settings.mipmaps;
|
||||
width = settings.width;
|
||||
height = settings.height;
|
||||
pixelWidth = (int) ((width * settings.dpiScale) + 0.5);
|
||||
pixelHeight = (int) ((height * settings.dpiScale) + 0.5);
|
||||
|
||||
format = settings.format;
|
||||
|
||||
if (texType == TEXTURE_VOLUME)
|
||||
depth = settings.layers;
|
||||
else if (texType == TEXTURE_2D_ARRAY)
|
||||
layers = settings.layers;
|
||||
|
||||
if (width <= 0 || height <= 0 || layers <= 0)
|
||||
throw love::Exception("Canvas dimensions must be greater than 0.");
|
||||
|
||||
if (texType != TEXTURE_2D && settings.msaa > 1)
|
||||
throw love::Exception("MSAA is only supported for Canvases with the 2D texture type.");
|
||||
|
||||
if (settings.readable.hasValue)
|
||||
readable = settings.readable.value;
|
||||
else
|
||||
readable = !isPixelFormatDepthStencil(format);
|
||||
|
||||
if (readable && isPixelFormatDepthStencil(format) && settings.msaa > 1)
|
||||
throw love::Exception("Readable depth/stencil Canvases with MSAA are not currently supported.");
|
||||
|
||||
if ((!readable || settings.msaa > 1) && mipmapsMode != MIPMAPS_NONE)
|
||||
throw love::Exception("Non-readable and MSAA textures cannot have mipmaps.");
|
||||
|
||||
if (mipmapsMode != MIPMAPS_NONE)
|
||||
mipmapCount = getTotalMipmapCount(pixelWidth, pixelHeight, depth);
|
||||
|
||||
auto gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
|
||||
const Graphics::Capabilities &caps = gfx->getCapabilities();
|
||||
|
||||
if (!gfx->isPixelFormatSupported(format, renderTarget, readable, sRGB))
|
||||
{
|
||||
const char *fstr = "rgba8";
|
||||
const char *readablestr = "";
|
||||
if (readable != !isPixelFormatDepthStencil(format))
|
||||
readablestr = readable ? " readable" : " non-readable";
|
||||
love::getConstant(format, fstr);
|
||||
throw love::Exception("The %s%s canvas format is not supported by your graphics drivers.", fstr, readablestr);
|
||||
}
|
||||
|
||||
if (getRequestedMSAA() > 1 && texType != TEXTURE_2D)
|
||||
throw love::Exception("MSAA is only supported for 2D texture types.");
|
||||
|
||||
if (!readable && texType != TEXTURE_2D)
|
||||
throw love::Exception("Non-readable pixel formats are only supported for 2D texture types.");
|
||||
|
||||
if (!caps.textureTypes[texType])
|
||||
{
|
||||
const char *textypestr = "unknown";
|
||||
Texture::getConstant(texType, textypestr);
|
||||
throw love::Exception("%s textures are not supported on this system!", textypestr);
|
||||
}
|
||||
|
||||
validateDimensions(true);
|
||||
}
|
||||
|
||||
Canvas::~Canvas()
|
||||
{
|
||||
}
|
||||
|
||||
bool Canvas::getConstant(const char *in, SettingType &out)
|
||||
{
|
||||
return settingTypes.find(in, out);
|
||||
}
|
||||
|
||||
bool Canvas::getConstant(SettingType in, const char *&out)
|
||||
{
|
||||
return settingTypes.find(in, out);
|
||||
}
|
||||
|
||||
const char *Canvas::getConstant(SettingType in)
|
||||
{
|
||||
const char *name = nullptr;
|
||||
getConstant(in, name);
|
||||
return name;
|
||||
}
|
||||
|
||||
std::vector<std::string> Canvas::getConstants(SettingType)
|
||||
{
|
||||
return settingTypes.getNames();
|
||||
}
|
||||
|
||||
StringMap<Canvas::SettingType, Canvas::SETTING_MAX_ENUM>::Entry Canvas::settingTypeEntries[] =
|
||||
{
|
||||
// Width / height / layers are currently omittted because they're separate
|
||||
// arguments to newCanvas in the wrapper code.
|
||||
{ "mipmaps", SETTING_MIPMAPS },
|
||||
{ "format", SETTING_FORMAT },
|
||||
{ "type", SETTING_TYPE },
|
||||
{ "dpiscale", SETTING_DPI_SCALE },
|
||||
{ "msaa", SETTING_MSAA },
|
||||
{ "readable", SETTING_READABLE },
|
||||
};
|
||||
|
||||
StringMap<Canvas::SettingType, Canvas::SETTING_MAX_ENUM> Canvas::settingTypes(Canvas::settingTypeEntries, sizeof(Canvas::settingTypeEntries));
|
||||
|
||||
} // graphics
|
||||
} // love
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2020 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "image/Image.h"
|
||||
#include "image/ImageData.h"
|
||||
#include "Texture.h"
|
||||
#include "common/Optional.h"
|
||||
#include "common/StringMap.h"
|
||||
|
||||
namespace love
|
||||
{
|
||||
namespace graphics
|
||||
{
|
||||
|
||||
class Graphics;
|
||||
|
||||
class Canvas : public Texture
|
||||
{
|
||||
public:
|
||||
|
||||
static love::Type type;
|
||||
|
||||
enum SettingType
|
||||
{
|
||||
SETTING_WIDTH,
|
||||
SETTING_HEIGHT,
|
||||
SETTING_LAYERS,
|
||||
SETTING_MIPMAPS,
|
||||
SETTING_FORMAT,
|
||||
SETTING_TYPE,
|
||||
SETTING_DPI_SCALE,
|
||||
SETTING_MSAA,
|
||||
SETTING_READABLE,
|
||||
SETTING_MAX_ENUM
|
||||
};
|
||||
|
||||
struct Settings
|
||||
{
|
||||
int width = 1;
|
||||
int height = 1;
|
||||
int layers = 1; // depth for 3D textures
|
||||
MipmapsMode mipmaps = MIPMAPS_NONE;
|
||||
PixelFormat format = PIXELFORMAT_NORMAL;
|
||||
TextureType type = TEXTURE_2D;
|
||||
float dpiScale = 1.0f;
|
||||
int msaa = 0;
|
||||
OptionalBool readable;
|
||||
};
|
||||
|
||||
Canvas(const Settings &settings);
|
||||
virtual ~Canvas();
|
||||
|
||||
static bool getConstant(const char *in, SettingType &out);
|
||||
static bool getConstant(SettingType in, const char *&out);
|
||||
static const char *getConstant(SettingType in);
|
||||
static std::vector<std::string> getConstants(SettingType);
|
||||
|
||||
protected:
|
||||
|
||||
Settings settings;
|
||||
|
||||
private:
|
||||
|
||||
static StringMap<SettingType, SETTING_MAX_ENUM>::Entry settingTypeEntries[];
|
||||
static StringMap<SettingType, SETTING_MAX_ENUM> settingTypes;
|
||||
|
||||
}; // Canvas
|
||||
|
||||
} // graphics
|
||||
} // love
|
||||
@@ -150,8 +150,11 @@ void Font::createTexture()
|
||||
textures.pop_back();
|
||||
}
|
||||
|
||||
Image::Settings settings;
|
||||
texture = gfx->newImage(TEXTURE_2D, pixelFormat, size.width, size.height, 1, settings);
|
||||
Texture::Settings settings;
|
||||
settings.format = pixelFormat;
|
||||
settings.width = size.width;
|
||||
settings.height = size.height;
|
||||
texture = gfx->newImage(settings, nullptr);
|
||||
texture->setSamplerState(samplerState);
|
||||
|
||||
{
|
||||
|
||||
@@ -820,7 +820,7 @@ Texture *Graphics::getTemporaryTexture(PixelFormat format, int w, int h, int sam
|
||||
|
||||
if (texture == nullptr)
|
||||
{
|
||||
Canvas::Settings settings;
|
||||
Texture::Settings settings;
|
||||
settings.format = format;
|
||||
settings.width = w;
|
||||
settings.height = h;
|
||||
|
||||
@@ -32,13 +32,11 @@
|
||||
#include "StreamBuffer.h"
|
||||
#include "vertex.h"
|
||||
#include "Texture.h"
|
||||
#include "Canvas.h"
|
||||
#include "Font.h"
|
||||
#include "ShaderStage.h"
|
||||
#include "Shader.h"
|
||||
#include "Quad.h"
|
||||
#include "Mesh.h"
|
||||
#include "Image.h"
|
||||
#include "Deprecations.h"
|
||||
#include "renderstate.h"
|
||||
#include "math/Transform.h"
|
||||
@@ -428,8 +426,7 @@ public:
|
||||
// Implements Module.
|
||||
virtual ModuleType getModuleType() const { return M_GRAPHICS; }
|
||||
|
||||
virtual Texture *newImage(const Texture::Slices &data, const Image::Settings &settings) = 0;
|
||||
virtual Texture *newImage(TextureType textype, PixelFormat format, int width, int height, int slices, const Image::Settings &settings) = 0;
|
||||
virtual Texture *newImage(const Texture::Settings &settings, const Texture::Slices *data) = 0;
|
||||
|
||||
Quad *newQuad(Quad::Viewport v, double sw, double sh);
|
||||
Font *newFont(love::font::Rasterizer *data);
|
||||
@@ -439,7 +436,7 @@ public:
|
||||
SpriteBatch *newSpriteBatch(Texture *texture, int size, vertex::Usage usage);
|
||||
ParticleSystem *newParticleSystem(Texture *texture, int size);
|
||||
|
||||
virtual Texture *newCanvas(const Canvas::Settings &settings) = 0;
|
||||
virtual Texture *newCanvas(const Texture::Settings &settings) = 0;
|
||||
|
||||
ShaderStage *newShaderStage(ShaderStage::StageType stage, const std::string &source);
|
||||
Shader *newShader(const std::string &vertex, const std::string &pixel);
|
||||
|
||||
@@ -1,140 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2020 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
**/
|
||||
|
||||
#include "Image.h"
|
||||
#include "Graphics.h"
|
||||
|
||||
// C++
|
||||
#include <algorithm>
|
||||
|
||||
namespace love
|
||||
{
|
||||
namespace graphics
|
||||
{
|
||||
|
||||
love::Type Image::type("Image", &Texture::type);
|
||||
|
||||
Image::Image(TextureType textype, const Settings &settings)
|
||||
: Texture(textype)
|
||||
, settings(settings)
|
||||
{
|
||||
renderTarget = false;
|
||||
sRGB = isGammaCorrect() && !settings.linear;
|
||||
}
|
||||
|
||||
Image::Image(TextureType textype, PixelFormat format, int width, int height, int slices, const Settings &settings)
|
||||
: Image(textype, settings)
|
||||
{
|
||||
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, 1, settings);
|
||||
}
|
||||
|
||||
Image::Image(const Slices &slices, const Settings &settings)
|
||||
: 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(), dataMipmaps, settings);
|
||||
}
|
||||
|
||||
Image::~Image()
|
||||
{
|
||||
}
|
||||
|
||||
void Image::init(PixelFormat fmt, int w, int h, int dataMipmaps, const Settings &settings)
|
||||
{
|
||||
Graphics *gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
|
||||
if (gfx != nullptr && !gfx->isPixelFormatSupported(fmt, renderTarget, readable, sRGB))
|
||||
{
|
||||
const char *str;
|
||||
if (love::getConstant(fmt, str))
|
||||
{
|
||||
throw love::Exception("Cannot create image: "
|
||||
"%s%s images are not supported on this system.", sRGB ? "sRGB " : "", str);
|
||||
}
|
||||
else
|
||||
throw love::Exception("cannot create image: format is not supported on this system.");
|
||||
}
|
||||
|
||||
pixelWidth = w;
|
||||
pixelHeight = h;
|
||||
mipmapsMode = settings.mipmaps ? MIPMAPS_MANUAL : MIPMAPS_NONE;
|
||||
|
||||
width = (int) (pixelWidth / settings.dpiScale + 0.5);
|
||||
height = (int) (pixelHeight / settings.dpiScale + 0.5);
|
||||
|
||||
format = fmt;
|
||||
|
||||
if (mipmapsMode == MIPMAPS_NONE || (isCompressed() && dataMipmaps <= 1))
|
||||
mipmapCount = 1;
|
||||
else
|
||||
mipmapCount = getTotalMipmapCount(w, h, depth);
|
||||
|
||||
initQuad();
|
||||
}
|
||||
|
||||
bool Image::getConstant(const char *in, SettingType &out)
|
||||
{
|
||||
return settingTypes.find(in, out);
|
||||
}
|
||||
|
||||
bool Image::getConstant(SettingType in, const char *&out)
|
||||
{
|
||||
return settingTypes.find(in, out);
|
||||
}
|
||||
|
||||
const char *Image::getConstant(SettingType in)
|
||||
{
|
||||
const char *name = nullptr;
|
||||
getConstant(in, name);
|
||||
return name;
|
||||
}
|
||||
|
||||
std::vector<std::string> Image::getConstants(SettingType)
|
||||
{
|
||||
return settingTypes.getNames();
|
||||
}
|
||||
|
||||
StringMap<Image::SettingType, Image::SETTING_MAX_ENUM>::Entry Image::settingTypeEntries[] =
|
||||
{
|
||||
{ "mipmaps", SETTING_MIPMAPS },
|
||||
{ "linear", SETTING_LINEAR },
|
||||
{ "dpiscale", SETTING_DPI_SCALE },
|
||||
};
|
||||
|
||||
StringMap<Image::SettingType, Image::SETTING_MAX_ENUM> Image::settingTypes(Image::settingTypeEntries, sizeof(Image::settingTypeEntries));
|
||||
|
||||
} // graphics
|
||||
} // love
|
||||
@@ -1,82 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2020 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
// LOVE
|
||||
#include "common/config.h"
|
||||
#include "common/StringMap.h"
|
||||
#include "common/math.h"
|
||||
#include "Texture.h"
|
||||
|
||||
namespace love
|
||||
{
|
||||
namespace graphics
|
||||
{
|
||||
|
||||
class Image : public Texture
|
||||
{
|
||||
public:
|
||||
|
||||
static love::Type type;
|
||||
|
||||
enum SettingType
|
||||
{
|
||||
SETTING_MIPMAPS,
|
||||
SETTING_LINEAR,
|
||||
SETTING_DPI_SCALE,
|
||||
SETTING_MAX_ENUM
|
||||
};
|
||||
|
||||
struct Settings
|
||||
{
|
||||
bool mipmaps = false;
|
||||
bool linear = false;
|
||||
float dpiScale = 1.0f;
|
||||
};
|
||||
|
||||
virtual ~Image();
|
||||
|
||||
static bool getConstant(const char *in, SettingType &out);
|
||||
static bool getConstant(SettingType in, const char *&out);
|
||||
static const char *getConstant(SettingType in);
|
||||
static std::vector<std::string> getConstants(SettingType);
|
||||
|
||||
protected:
|
||||
|
||||
Image(const Slices &data, const Settings &settings);
|
||||
Image(TextureType textype, PixelFormat format, int width, int height, int slices, const Settings &settings);
|
||||
|
||||
// The settings used to initialize this Image.
|
||||
Settings settings;
|
||||
|
||||
private:
|
||||
|
||||
Image(TextureType textype, const Settings &settings);
|
||||
|
||||
void init(PixelFormat fmt, int w, int h, int dataMipmaps, const Settings &settings);
|
||||
|
||||
static StringMap<SettingType, SETTING_MAX_ENUM>::Entry settingTypeEntries[];
|
||||
static StringMap<SettingType, SETTING_MAX_ENUM> settingTypes;
|
||||
|
||||
}; // Image
|
||||
|
||||
} // graphics
|
||||
} // love
|
||||
@@ -159,28 +159,122 @@ 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)
|
||||
Texture::Texture(const Settings &settings, const Slices *slices)
|
||||
: texType(settings.type)
|
||||
, format(settings.format)
|
||||
, renderTarget(settings.renderTarget)
|
||||
, readable(true)
|
||||
, mipmapsMode(MIPMAPS_NONE)
|
||||
, sRGB(false)
|
||||
, width(0)
|
||||
, height(0)
|
||||
, depth(1)
|
||||
, layers(1)
|
||||
, mipmapsMode(settings.mipmaps)
|
||||
, sRGB(isGammaCorrect() && !settings.linear)
|
||||
, width(settings.width)
|
||||
, height(settings.height)
|
||||
, depth(settings.type == TEXTURE_VOLUME ? settings.layers : 1)
|
||||
, layers(settings.type == TEXTURE_2D_ARRAY ? settings.layers : 1)
|
||||
, mipmapCount(1)
|
||||
, pixelWidth(0)
|
||||
, pixelHeight(0)
|
||||
, requestedMSAA(1)
|
||||
, requestedMSAA(settings.msaa)
|
||||
, samplerState()
|
||||
, graphicsMemorySize(0)
|
||||
, usingDefaultTexture(false)
|
||||
{
|
||||
auto gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
|
||||
if (gfx != nullptr)
|
||||
samplerState = gfx->getDefaultSamplerState();
|
||||
|
||||
if (slices != nullptr && slices->getMipmapCount() > 0 && slices->getSliceCount() > 0)
|
||||
{
|
||||
texType = slices->getTextureType();
|
||||
|
||||
int dataMipmaps = 1;
|
||||
if (slices->validate() && slices->getMipmapCount() > 1)
|
||||
dataMipmaps = slices->getMipmapCount();
|
||||
|
||||
love::image::ImageDataBase *slice = slices->get(0, 0);
|
||||
|
||||
format = slice->getFormat();
|
||||
|
||||
pixelWidth = slice->getWidth();
|
||||
pixelHeight = slice->getHeight();
|
||||
|
||||
if (texType == TEXTURE_2D_ARRAY)
|
||||
layers = slices->getSliceCount();
|
||||
else if (texType == TEXTURE_VOLUME)
|
||||
depth = slices->getSliceCount();
|
||||
|
||||
width = (int) (pixelWidth / settings.dpiScale + 0.5);
|
||||
height = (int) (pixelHeight / settings.dpiScale + 0.5);
|
||||
|
||||
if (isCompressed() && dataMipmaps <= 1)
|
||||
mipmapsMode = MIPMAPS_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isCompressed())
|
||||
throw love::Exception("Compressed textures must be created with initial data.");
|
||||
|
||||
pixelWidth = (int) ((width * settings.dpiScale) + 0.5);
|
||||
pixelHeight = (int) ((height * settings.dpiScale) + 0.5);
|
||||
}
|
||||
|
||||
if (settings.readable.hasValue)
|
||||
readable = settings.readable.value;
|
||||
else
|
||||
readable = !isPixelFormatDepthStencil(format);
|
||||
|
||||
format = gfx->getSizedFormat(format, renderTarget, readable, sRGB);
|
||||
|
||||
if (mipmapsMode == MIPMAPS_AUTO && isCompressed())
|
||||
mipmapsMode = MIPMAPS_MANUAL;
|
||||
|
||||
if (mipmapsMode != MIPMAPS_NONE)
|
||||
mipmapCount = getTotalMipmapCount(pixelWidth, pixelHeight, depth);
|
||||
|
||||
if (pixelWidth <= 0 || pixelHeight <= 0 || layers <= 0 || depth <= 0)
|
||||
throw love::Exception("Texture dimensions must be greater than 0.");
|
||||
|
||||
if (texType != TEXTURE_2D && requestedMSAA > 1)
|
||||
throw love::Exception("MSAA is only supported for textures with the 2D texture type.");
|
||||
|
||||
if (readable && isPixelFormatDepthStencil(format) && settings.msaa > 1)
|
||||
throw love::Exception("Readable depth/stencil textures with MSAA are not currently supported.");
|
||||
|
||||
if ((!readable || settings.msaa > 1) && mipmapsMode != MIPMAPS_NONE)
|
||||
throw love::Exception("Non-readable and MSAA textures cannot have mipmaps.");
|
||||
|
||||
if (!readable && texType != TEXTURE_2D)
|
||||
throw love::Exception("Non-readable pixel formats are only supported for 2D texture types.");
|
||||
|
||||
if (isCompressed() && renderTarget)
|
||||
throw love::Exception("Compressed textures cannot be render targets.");
|
||||
|
||||
if (!gfx->isPixelFormatSupported(format, renderTarget, readable, sRGB))
|
||||
{
|
||||
const char *fstr = "unknown";
|
||||
love::getConstant(format, fstr);
|
||||
|
||||
const char *readablestr = "";
|
||||
if (readable != !isPixelFormatDepthStencil(format))
|
||||
readablestr = readable ? " readable" : " non-readable";
|
||||
|
||||
const char *rtstr = "";
|
||||
if (renderTarget)
|
||||
rtstr = " as a render target";
|
||||
|
||||
throw love::Exception("The %s%s pixel format is not supported%s on this system.", fstr, readablestr, rtstr);
|
||||
}
|
||||
|
||||
if (!gfx->getCapabilities().textureTypes[texType])
|
||||
{
|
||||
const char *textypestr = "unknown";
|
||||
Texture::getConstant(texType, textypestr);
|
||||
throw love::Exception("%s textures are not supported on this system.", textypestr);
|
||||
}
|
||||
|
||||
validateDimensions(!renderTarget);
|
||||
|
||||
samplerState = gfx->getDefaultSamplerState();
|
||||
|
||||
initQuad();
|
||||
|
||||
++textureCount;
|
||||
}
|
||||
|
||||
@@ -780,6 +874,42 @@ bool Texture::Slices::validate() const
|
||||
return true;
|
||||
}
|
||||
|
||||
static StringMap<TextureType, TEXTURE_MAX_ENUM>::Entry texTypeEntries[] =
|
||||
{
|
||||
{ "2d", TEXTURE_2D },
|
||||
{ "volume", TEXTURE_VOLUME },
|
||||
{ "array", TEXTURE_2D_ARRAY },
|
||||
{ "cube", TEXTURE_CUBE },
|
||||
};
|
||||
|
||||
static StringMap<TextureType, TEXTURE_MAX_ENUM> texTypes(texTypeEntries, sizeof(texTypeEntries));
|
||||
|
||||
static StringMap<Texture::MipmapsMode, Texture::MIPMAPS_MAX_ENUM>::Entry mipmapEntries[] =
|
||||
{
|
||||
{ "none", Texture::MIPMAPS_NONE },
|
||||
{ "manual", Texture::MIPMAPS_MANUAL },
|
||||
{ "auto", Texture::MIPMAPS_AUTO },
|
||||
};
|
||||
|
||||
static StringMap<Texture::MipmapsMode, Texture::MIPMAPS_MAX_ENUM> mipmapModes(mipmapEntries, sizeof(mipmapEntries));
|
||||
|
||||
static StringMap<Texture::SettingType, Texture::SETTING_MAX_ENUM>::Entry settingTypeEntries[] =
|
||||
{
|
||||
{ "width", Texture::SETTING_WIDTH },
|
||||
{ "height", Texture::SETTING_HEIGHT },
|
||||
{ "layers", Texture::SETTING_LAYERS },
|
||||
{ "mipmaps", Texture::SETTING_MIPMAPS },
|
||||
{ "format", Texture::SETTING_FORMAT },
|
||||
{ "linear", Texture::SETTING_LINEAR },
|
||||
{ "type", Texture::SETTING_TYPE },
|
||||
{ "dpiscale", Texture::SETTING_DPI_SCALE },
|
||||
{ "msaa", Texture::SETTING_MSAA },
|
||||
{ "rendertarget", Texture::SETTING_RENDER_TARGET },
|
||||
{ "readable", Texture::SETTING_READABLE },
|
||||
};
|
||||
|
||||
static StringMap<Texture::SettingType, Texture::SETTING_MAX_ENUM> settingTypes(settingTypeEntries, sizeof(settingTypeEntries));
|
||||
|
||||
bool Texture::getConstant(const char *in, TextureType &out)
|
||||
{
|
||||
return texTypes.find(in, out);
|
||||
@@ -795,25 +925,6 @@ std::vector<std::string> Texture::getConstants(TextureType)
|
||||
return texTypes.getNames();
|
||||
}
|
||||
|
||||
StringMap<TextureType, TEXTURE_MAX_ENUM>::Entry Texture::texTypeEntries[] =
|
||||
{
|
||||
{ "2d", TEXTURE_2D },
|
||||
{ "volume", TEXTURE_VOLUME },
|
||||
{ "array", TEXTURE_2D_ARRAY },
|
||||
{ "cube", TEXTURE_CUBE },
|
||||
};
|
||||
|
||||
StringMap<TextureType, TEXTURE_MAX_ENUM> Texture::texTypes(Texture::texTypeEntries, sizeof(Texture::texTypeEntries));
|
||||
|
||||
static StringMap<Texture::MipmapsMode, Texture::MIPMAPS_MAX_ENUM>::Entry mipmapEntries[] =
|
||||
{
|
||||
{ "none", Texture::MIPMAPS_NONE },
|
||||
{ "manual", Texture::MIPMAPS_MANUAL },
|
||||
{ "auto", Texture::MIPMAPS_AUTO },
|
||||
};
|
||||
|
||||
static StringMap<Texture::MipmapsMode, Texture::MIPMAPS_MAX_ENUM> mipmapModes(mipmapEntries, sizeof(mipmapEntries));
|
||||
|
||||
bool Texture::getConstant(const char *in, MipmapsMode &out)
|
||||
{
|
||||
return mipmapModes.find(in, out);
|
||||
@@ -829,5 +940,27 @@ std::vector<std::string> Texture::getConstants(MipmapsMode)
|
||||
return mipmapModes.getNames();
|
||||
}
|
||||
|
||||
bool Texture::getConstant(const char *in, SettingType &out)
|
||||
{
|
||||
return settingTypes.find(in, out);
|
||||
}
|
||||
|
||||
bool Texture::getConstant(SettingType in, const char *&out)
|
||||
{
|
||||
return settingTypes.find(in, out);
|
||||
}
|
||||
|
||||
const char *Texture::getConstant(SettingType in)
|
||||
{
|
||||
const char *name = nullptr;
|
||||
getConstant(in, name);
|
||||
return name;
|
||||
}
|
||||
|
||||
std::vector<std::string> Texture::getConstants(SettingType)
|
||||
{
|
||||
return settingTypes.getNames();
|
||||
}
|
||||
|
||||
} // graphics
|
||||
} // love
|
||||
|
||||
@@ -137,6 +137,38 @@ public:
|
||||
MIPMAPS_MAX_ENUM
|
||||
};
|
||||
|
||||
enum SettingType
|
||||
{
|
||||
SETTING_WIDTH,
|
||||
SETTING_HEIGHT,
|
||||
SETTING_LAYERS,
|
||||
SETTING_MIPMAPS,
|
||||
SETTING_FORMAT,
|
||||
SETTING_LINEAR,
|
||||
SETTING_TYPE,
|
||||
SETTING_DPI_SCALE,
|
||||
SETTING_MSAA,
|
||||
SETTING_RENDER_TARGET,
|
||||
SETTING_READABLE,
|
||||
SETTING_MAX_ENUM
|
||||
};
|
||||
|
||||
// Size and format will be overridden by ImageData when supplied.
|
||||
struct Settings
|
||||
{
|
||||
int width = 1;
|
||||
int height = 1;
|
||||
int layers = 1; // depth for 3D textures
|
||||
TextureType type = TEXTURE_2D;
|
||||
MipmapsMode mipmaps = MIPMAPS_NONE;
|
||||
PixelFormat format = PIXELFORMAT_NORMAL;
|
||||
bool linear = false;
|
||||
float dpiScale = 1.0f;
|
||||
int msaa = 0;
|
||||
bool renderTarget = false;
|
||||
OptionalBool readable;
|
||||
};
|
||||
|
||||
struct Slices
|
||||
{
|
||||
public:
|
||||
@@ -169,7 +201,7 @@ public:
|
||||
|
||||
static int64 totalGraphicsMemory;
|
||||
|
||||
Texture(TextureType texType);
|
||||
Texture(const Settings &settings, const Slices *slices);
|
||||
virtual ~Texture();
|
||||
|
||||
// Drawable.
|
||||
@@ -234,6 +266,11 @@ public:
|
||||
static bool getConstant(MipmapsMode in, const char *&out);
|
||||
static std::vector<std::string> getConstants(MipmapsMode);
|
||||
|
||||
static bool getConstant(const char *in, SettingType &out);
|
||||
static bool getConstant(SettingType in, const char *&out);
|
||||
static const char *getConstant(SettingType in);
|
||||
static std::vector<std::string> getConstants(SettingType);
|
||||
|
||||
protected:
|
||||
|
||||
void initQuad();
|
||||
@@ -276,11 +313,6 @@ protected:
|
||||
// back to a default texture.
|
||||
bool usingDefaultTexture;
|
||||
|
||||
private:
|
||||
|
||||
static StringMap<TextureType, TEXTURE_MAX_ENUM>::Entry texTypeEntries[];
|
||||
static StringMap<TextureType, TEXTURE_MAX_ENUM> texTypes;
|
||||
|
||||
}; // Texture
|
||||
|
||||
} // graphics
|
||||
|
||||
@@ -79,11 +79,14 @@ Video::Video(Graphics *gfx, love::video::VideoStream *stream, float dpiscale)
|
||||
|
||||
const unsigned char *data[3] = {frame->yplane, frame->cbplane, frame->crplane};
|
||||
|
||||
Image::Settings settings;
|
||||
Texture::Settings settings;
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
Texture *tex = gfx->newImage(TEXTURE_2D, PIXELFORMAT_R8_UNORM, widths[i], heights[i], 1, settings);
|
||||
settings.width = widths[i];
|
||||
settings.height = heights[i];
|
||||
settings.format = PIXELFORMAT_R8_UNORM;
|
||||
Texture *tex = gfx->newImage(settings, nullptr);
|
||||
|
||||
tex->setSamplerState(samplerState);
|
||||
|
||||
|
||||
@@ -183,7 +183,7 @@ static bool createRenderbuffer(int width, int height, int &samples, PixelFormat
|
||||
}
|
||||
|
||||
Canvas::Canvas(const Settings &settings)
|
||||
: love::graphics::Canvas(settings)
|
||||
: love::graphics::Texture(settings, nullptr)
|
||||
, fbo(0)
|
||||
, texture(0)
|
||||
, renderbuffer(0)
|
||||
@@ -346,7 +346,7 @@ ptrdiff_t Canvas::getHandle() const
|
||||
|
||||
love::image::ImageData *Canvas::newImageData(love::image::Image *module, int slice, int mipmap, const Rect &r)
|
||||
{
|
||||
love::image::ImageData *data = love::graphics::Canvas::newImageData(module, slice, mipmap, r);
|
||||
love::image::ImageData *data = love::graphics::Texture::newImageData(module, slice, mipmap, r);
|
||||
|
||||
bool isSRGB = false;
|
||||
OpenGL::TextureFormat fmt = gl.convertPixelFormat(data->getFormat(), false, isSRGB);
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include "common/config.h"
|
||||
#include "common/Color.h"
|
||||
#include "common/int.h"
|
||||
#include "graphics/Canvas.h"
|
||||
#include "graphics/Texture.h"
|
||||
#include "graphics/Volatile.h"
|
||||
#include "OpenGL.h"
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace graphics
|
||||
namespace opengl
|
||||
{
|
||||
|
||||
class Canvas final : public love::graphics::Canvas, public Volatile
|
||||
class Canvas final : public love::graphics::Texture, public Volatile
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
@@ -130,17 +130,12 @@ love::graphics::StreamBuffer *Graphics::newStreamBuffer(BufferType type, size_t
|
||||
return CreateStreamBuffer(type, size);
|
||||
}
|
||||
|
||||
love::graphics::Texture *Graphics::newImage(const Texture::Slices &data, const Image::Settings &settings)
|
||||
love::graphics::Texture *Graphics::newImage(const Texture::Settings &settings, const Texture::Slices *data)
|
||||
{
|
||||
return new Image(data, settings);
|
||||
return new Image(settings, data);
|
||||
}
|
||||
|
||||
love::graphics::Texture *Graphics::newImage(TextureType textype, PixelFormat format, int width, int height, int slices, const Image::Settings &settings)
|
||||
{
|
||||
return new Image(textype, format, width, height, slices, settings);
|
||||
}
|
||||
|
||||
love::graphics::Texture *Graphics::newCanvas(const Canvas::Settings &settings)
|
||||
love::graphics::Texture *Graphics::newCanvas(const Texture::Settings &settings)
|
||||
{
|
||||
return new Canvas(settings);
|
||||
}
|
||||
|
||||
@@ -60,9 +60,8 @@ public:
|
||||
// Implements Module.
|
||||
const char *getName() const override;
|
||||
|
||||
love::graphics::Texture *newImage(const Texture::Slices &data, const Image::Settings &settings) override;
|
||||
love::graphics::Texture *newImage(TextureType textype, PixelFormat format, int width, int height, int slices, const Image::Settings &settings) override;
|
||||
love::graphics::Texture *newCanvas(const Canvas::Settings &settings) override;
|
||||
love::graphics::Texture *newImage(const Texture::Settings &settings, const Texture::Slices *data) override;
|
||||
love::graphics::Texture *newCanvas(const Texture::Settings &settings) override;
|
||||
love::graphics::Buffer *newBuffer(size_t size, const void *data, BufferType type, vertex::Usage usage, uint32 mapflags) override;
|
||||
|
||||
void setViewportSize(int width, int height, int pixelwidth, int pixelheight) override;
|
||||
|
||||
@@ -33,19 +33,13 @@ namespace graphics
|
||||
namespace opengl
|
||||
{
|
||||
|
||||
Image::Image(TextureType textype, PixelFormat format, int width, int height, int slices, const Settings &settings)
|
||||
: love::graphics::Image(textype, format, width, height, slices, settings)
|
||||
, slices(textype)
|
||||
, texture(0)
|
||||
{
|
||||
loadVolatile();
|
||||
}
|
||||
|
||||
Image::Image(const Slices &slices, const Settings &settings)
|
||||
: love::graphics::Image(slices, settings)
|
||||
, slices(slices)
|
||||
Image::Image(const Settings &settings, const Slices *data)
|
||||
: love::graphics::Texture(settings, data)
|
||||
, slices(settings.type)
|
||||
, texture(0)
|
||||
{
|
||||
if (data != nullptr)
|
||||
slices = *data;
|
||||
loadVolatile();
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#pragma once
|
||||
|
||||
// LOVE
|
||||
#include "graphics/Image.h"
|
||||
#include "graphics/Texture.h"
|
||||
#include "graphics/Volatile.h"
|
||||
|
||||
// OpenGL
|
||||
@@ -34,12 +34,11 @@ namespace graphics
|
||||
namespace opengl
|
||||
{
|
||||
|
||||
class Image final : public love::graphics::Image, public Volatile
|
||||
class Image final : public love::graphics::Texture, public Volatile
|
||||
{
|
||||
public:
|
||||
|
||||
Image(const Slices &data, const Settings &settings);
|
||||
Image(TextureType textype, PixelFormat format, int width, int height, int slices, const Settings &settings);
|
||||
Image(const Settings &settings, const Slices *data);
|
||||
|
||||
virtual ~Image();
|
||||
|
||||
|
||||
@@ -700,19 +700,19 @@ static void parseDPIScale(Data *d, float *dpiscale)
|
||||
}
|
||||
}
|
||||
|
||||
static Image::Settings w__optImageSettings(lua_State *L, int idx, bool &setdpiscale)
|
||||
static Texture::Settings w__optImageSettings(lua_State *L, int idx, bool &setdpiscale)
|
||||
{
|
||||
Image::Settings s;
|
||||
Texture::Settings s;
|
||||
|
||||
setdpiscale = false;
|
||||
if (!lua_isnoneornil(L, idx))
|
||||
{
|
||||
luax_checktablefields<Image::SettingType>(L, idx, "image setting name", Image::getConstant);
|
||||
luax_checktablefields<Texture::SettingType>(L, idx, "image setting name", Texture::getConstant);
|
||||
|
||||
s.mipmaps = luax_boolflag(L, idx, Image::getConstant(Image::SETTING_MIPMAPS), s.mipmaps);
|
||||
s.linear = luax_boolflag(L, idx, Image::getConstant(Image::SETTING_LINEAR), s.linear);
|
||||
s.mipmaps = luax_boolflag(L, idx, "mipmaps", false) ? Texture::MIPMAPS_MANUAL : Texture::MIPMAPS_NONE;
|
||||
s.linear = luax_boolflag(L, idx, Texture::getConstant(Texture::SETTING_LINEAR), s.linear);
|
||||
|
||||
lua_getfield(L, idx, Image::getConstant(Image::SETTING_DPI_SCALE));
|
||||
lua_getfield(L, idx, Texture::getConstant(Texture::SETTING_DPI_SCALE));
|
||||
if (lua_isnumber(L, -1))
|
||||
{
|
||||
s.dpiScale = (float) lua_tonumber(L, -1);
|
||||
@@ -757,11 +757,11 @@ getImageData(lua_State *L, int idx, bool allowcompressed, float *dpiscale)
|
||||
return std::make_pair(idata, cdata);
|
||||
}
|
||||
|
||||
static int w__pushNewImage(lua_State *L, Texture::Slices &slices, const Image::Settings &settings)
|
||||
static int w__pushNewImage(lua_State *L, Texture::Slices &slices, const Texture::Settings &settings)
|
||||
{
|
||||
StrongRef<Texture> i;
|
||||
luax_catchexcept(L,
|
||||
[&]() { i.set(instance()->newImage(slices, settings), Acquire::NORETAIN); },
|
||||
[&]() { i.set(instance()->newImage(settings, &slices), Acquire::NORETAIN); },
|
||||
[&](bool) { slices.clear(); }
|
||||
);
|
||||
|
||||
@@ -776,7 +776,7 @@ int w_newCubeImage(lua_State *L)
|
||||
Texture::Slices slices(TEXTURE_CUBE);
|
||||
|
||||
bool dpiscaleset = false;
|
||||
Image::Settings settings = w__optImageSettings(L, 2, dpiscaleset);
|
||||
Texture::Settings settings = w__optImageSettings(L, 2, dpiscaleset);
|
||||
float *autodpiscale = dpiscaleset ? nullptr : &settings.dpiScale;
|
||||
|
||||
auto imagemodule = Module::getInstance<love::image::Image>(Module::M_IMAGE);
|
||||
@@ -870,7 +870,7 @@ int w_newArrayImage(lua_State *L)
|
||||
Texture::Slices slices(TEXTURE_2D_ARRAY);
|
||||
|
||||
bool dpiscaleset = false;
|
||||
Image::Settings settings = w__optImageSettings(L, 2, dpiscaleset);
|
||||
Texture::Settings settings = w__optImageSettings(L, 2, dpiscaleset);
|
||||
float *autodpiscale = dpiscaleset ? nullptr : &settings.dpiScale;
|
||||
|
||||
if (lua_istable(L, 1))
|
||||
@@ -936,7 +936,7 @@ int w_newVolumeImage(lua_State *L)
|
||||
Texture::Slices slices(TEXTURE_VOLUME);
|
||||
|
||||
bool dpiscaleset = false;
|
||||
Image::Settings settings = w__optImageSettings(L, 2, dpiscaleset);
|
||||
Texture::Settings settings = w__optImageSettings(L, 2, dpiscaleset);
|
||||
float *autodpiscale = dpiscaleset ? nullptr : &settings.dpiScale;
|
||||
|
||||
if (lua_istable(L, 1))
|
||||
@@ -1007,7 +1007,7 @@ int w_newImage(lua_State *L)
|
||||
Texture::Slices slices(TEXTURE_2D);
|
||||
|
||||
bool dpiscaleset = false;
|
||||
Image::Settings settings = w__optImageSettings(L, 2, dpiscaleset);
|
||||
Texture::Settings settings = w__optImageSettings(L, 2, dpiscaleset);
|
||||
float *autodpiscale = dpiscaleset ? nullptr : &settings.dpiScale;
|
||||
|
||||
if (lua_istable(L, 1))
|
||||
@@ -1185,7 +1185,8 @@ int w_newCanvas(lua_State *L)
|
||||
{
|
||||
luax_checkgraphicscreated(L);
|
||||
|
||||
Canvas::Settings settings;
|
||||
Texture::Settings settings;
|
||||
settings.renderTarget = true;
|
||||
|
||||
// check if width and height are given. else default to screen dimensions.
|
||||
settings.width = (int) luaL_optinteger(L, 1, instance()->getWidth());
|
||||
@@ -1205,12 +1206,12 @@ int w_newCanvas(lua_State *L)
|
||||
|
||||
if (!lua_isnoneornil(L, startidx))
|
||||
{
|
||||
luax_checktablefields<Canvas::SettingType>(L, startidx, "canvas setting name", Canvas::getConstant);
|
||||
luax_checktablefields<Texture::SettingType>(L, startidx, "texture setting name", Texture::getConstant);
|
||||
|
||||
settings.dpiScale = (float) luax_numberflag(L, startidx, Canvas::getConstant(Canvas::SETTING_DPI_SCALE), settings.dpiScale);
|
||||
settings.msaa = luax_intflag(L, startidx, Canvas::getConstant(Canvas::SETTING_MSAA), settings.msaa);
|
||||
settings.dpiScale = (float) luax_numberflag(L, startidx, Texture::getConstant(Texture::SETTING_DPI_SCALE), settings.dpiScale);
|
||||
settings.msaa = luax_intflag(L, startidx, Texture::getConstant(Texture::SETTING_MSAA), settings.msaa);
|
||||
|
||||
lua_getfield(L, startidx, Canvas::getConstant(Canvas::SETTING_FORMAT));
|
||||
lua_getfield(L, startidx, Texture::getConstant(Texture::SETTING_FORMAT));
|
||||
if (!lua_isnoneornil(L, -1))
|
||||
{
|
||||
const char *str = luaL_checkstring(L, -1);
|
||||
@@ -1219,7 +1220,7 @@ int w_newCanvas(lua_State *L)
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, startidx, Canvas::getConstant(Canvas::SETTING_TYPE));
|
||||
lua_getfield(L, startidx, Texture::getConstant(Texture::SETTING_TYPE));
|
||||
if (!lua_isnoneornil(L, -1))
|
||||
{
|
||||
const char *str = luaL_checkstring(L, -1);
|
||||
@@ -1228,7 +1229,7 @@ int w_newCanvas(lua_State *L)
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, startidx, Canvas::getConstant(Canvas::SETTING_READABLE));
|
||||
lua_getfield(L, startidx, Texture::getConstant(Texture::SETTING_READABLE));
|
||||
if (!lua_isnoneornil(L, -1))
|
||||
{
|
||||
settings.readable.hasValue = true;
|
||||
@@ -1236,7 +1237,7 @@ int w_newCanvas(lua_State *L)
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, startidx, Canvas::getConstant(Canvas::SETTING_MIPMAPS));
|
||||
lua_getfield(L, startidx, Texture::getConstant(Texture::SETTING_MIPMAPS));
|
||||
if (!lua_isnoneornil(L, -1))
|
||||
{
|
||||
const char *str = luaL_checkstring(L, -1);
|
||||
|
||||
Reference in New Issue
Block a user