Browse Source

Move internal Slices class from Image to Texture

Alex Szpakowski 5 years ago
parent
commit
f24b1aa377

+ 1 - 1
src/modules/graphics/Graphics.h

@@ -429,7 +429,7 @@ public:
 	// Implements Module.
 	// Implements Module.
 	virtual ModuleType getModuleType() const { return M_GRAPHICS; }
 	virtual ModuleType getModuleType() const { return M_GRAPHICS; }
 
 
-	virtual Image *newImage(const Image::Slices &data, const Image::Settings &settings) = 0;
+	virtual Image *newImage(const Texture::Slices &data, const Image::Settings &settings) = 0;
 	virtual Image *newImage(TextureType textype, PixelFormat format, int width, int height, int slices, const Image::Settings &settings) = 0;
 	virtual Image *newImage(TextureType textype, PixelFormat format, int width, int height, int slices, const Image::Settings &settings) = 0;
 
 
 	Quad *newQuad(Quad::Viewport v, double sw, double sh);
 	Quad *newQuad(Quad::Viewport v, double sw, double sh);

+ 2 - 164
src/modules/graphics/Image.cpp

@@ -40,7 +40,7 @@ Image::Image(const Slices &data, const Settings &settings, bool validatedata)
 	, sRGB(isGammaCorrect() && !settings.linear)
 	, sRGB(isGammaCorrect() && !settings.linear)
 	, usingDefaultTexture(false)
 	, usingDefaultTexture(false)
 {
 {
-	if (validatedata && data.validate() == MIPMAPS_DATA)
+	if (validatedata && data.validate() && data.getMipmapCount() > 1)
 		mipmapsType = MIPMAPS_DATA;
 		mipmapsType = MIPMAPS_DATA;
 }
 }
 
 
@@ -182,7 +182,7 @@ bool Image::isCompressed() const
 
 
 bool Image::isFormatLinear() const
 bool Image::isFormatLinear() const
 {
 {
-	return isGammaCorrect() && !sRGB;
+	return isGammaCorrect() && !sRGB && format != PIXELFORMAT_sRGBA8_UNORM;
 }
 }
 
 
 Image::MipmapsType Image::getMipmapsType() const
 Image::MipmapsType Image::getMipmapsType() const
@@ -190,168 +190,6 @@ Image::MipmapsType Image::getMipmapsType() const
 	return mipmapsType;
 	return mipmapsType;
 }
 }
 
 
-Image::Slices::Slices(TextureType textype)
-	: textureType(textype)
-{
-}
-
-void Image::Slices::clear()
-{
-	data.clear();
-}
-
-void Image::Slices::set(int slice, int mipmap, love::image::ImageDataBase *d)
-{
-	if (textureType == TEXTURE_VOLUME)
-	{
-		if (mipmap >= (int) data.size())
-			data.resize(mipmap + 1);
-
-		if (slice >= (int) data[mipmap].size())
-			data[mipmap].resize(slice + 1);
-
-		data[mipmap][slice].set(d);
-	}
-	else
-	{
-		if (slice >= (int) data.size())
-			data.resize(slice + 1);
-
-		if (mipmap >= (int) data[slice].size())
-			data[slice].resize(mipmap + 1);
-
-		data[slice][mipmap].set(d);
-	}
-}
-
-love::image::ImageDataBase *Image::Slices::get(int slice, int mipmap) const
-{
-	if (slice < 0 || slice >= getSliceCount(mipmap))
-		return nullptr;
-
-	if (mipmap < 0 || mipmap >= getMipmapCount(slice))
-		return nullptr;
-
-	if (textureType == TEXTURE_VOLUME)
-		return data[mipmap][slice].get();
-	else
-		return data[slice][mipmap].get();
-}
-
-void Image::Slices::add(love::image::CompressedImageData *cdata, int startslice, int startmip, bool addallslices, bool addallmips)
-{
-	int slicecount = addallslices ? cdata->getSliceCount() : 1;
-	int mipcount = addallmips ? cdata->getMipmapCount() : 1;
-
-	for (int mip = 0; mip < mipcount; mip++)
-	{
-		for (int slice = 0; slice < slicecount; slice++)
-			set(startslice + slice, startmip + mip, cdata->getSlice(slice, mip));
-	}
-}
-
-int Image::Slices::getSliceCount(int mip) const
-{
-	if (textureType == TEXTURE_VOLUME)
-	{
-		if (mip < 0 || mip >= (int) data.size())
-			return 0;
-
-		return (int) data[mip].size();
-	}
-	else
-		return (int) data.size();
-}
-
-int Image::Slices::getMipmapCount(int slice) const
-{
-	if (textureType == TEXTURE_VOLUME)
-		return (int) data.size();
-	else
-	{
-		if (slice < 0 || slice >= (int) data.size())
-			return 0;
-
-		return data[slice].size();
-	}
-}
-
-Image::MipmapsType Image::Slices::validate() const
-{
-	int slicecount = getSliceCount();
-	int mipcount = getMipmapCount(0);
-
-	if (slicecount == 0 || mipcount == 0)
-		throw love::Exception("At least one ImageData or CompressedImageData is required!");
-
-	if (textureType == TEXTURE_CUBE && slicecount != 6)
-		throw love::Exception("Cube textures must have exactly 6 sides.");
-
-	image::ImageDataBase *firstdata = get(0, 0);
-
-	int w = firstdata->getWidth();
-	int h = firstdata->getHeight();
-	int depth = textureType == TEXTURE_VOLUME ? slicecount : 1;
-	PixelFormat format = firstdata->getFormat();
-
-	int expectedmips = Texture::getTotalMipmapCount(w, h, depth);
-
-	if (mipcount != expectedmips && mipcount != 1)
-		throw love::Exception("Image does not have all required mipmap levels (expected %d, got %d)", expectedmips, mipcount);
-
-	if (textureType == TEXTURE_CUBE && w != h)
-		throw love::Exception("Cube images must have equal widths and heights for each cube face.");
-
-	int mipw = w;
-	int miph = h;
-	int mipslices = slicecount;
-
-	for (int mip = 0; mip < mipcount; mip++)
-	{
-		if (textureType == TEXTURE_VOLUME)
-		{
-			slicecount = getSliceCount(mip);
-
-			if (slicecount != mipslices)
-				throw love::Exception("Invalid number of image data layers in mipmap level %d (expected %d, got %d)", mip+1, mipslices, slicecount);
-		}
-
-		for (int slice = 0; slice < slicecount; slice++)
-		{
-			auto slicedata = get(slice, mip);
-
-			if (slicedata == nullptr)
-				throw love::Exception("Missing image data (slice %d, mipmap level %d)", slice+1, mip+1);
-
-			int realw = slicedata->getWidth();
-			int realh = slicedata->getHeight();
-
-			if (getMipmapCount(slice) != mipcount)
-				throw love::Exception("All Image layers must have the same mipmap count.");
-
-			if (mipw != realw)
-				throw love::Exception("Width of image data (slice %d, mipmap level %d) is incorrect (expected %d, got %d)", slice+1, mip+1, mipw, realw);
-
-			if (miph != realh)
-				throw love::Exception("Height of image data (slice %d, mipmap level %d) is incorrect (expected %d, got %d)", slice+1, mip+1, miph, realh);
-
-			if (format != slicedata->getFormat())
-				throw love::Exception("All Image slices and mipmaps must have the same pixel format.");
-		}
-
-		mipw = std::max(mipw / 2, 1);
-		miph = std::max(miph / 2, 1);
-
-		if (textureType == TEXTURE_VOLUME)
-			mipslices = std::max(mipslices / 2, 1);
-	}
-
-	if (mipcount > 1)
-		return MIPMAPS_DATA;
-	else
-		return MIPMAPS_NONE;
-}
-
 bool Image::getConstant(const char *in, SettingType &out)
 bool Image::getConstant(const char *in, SettingType &out)
 {
 {
 	return settingTypes.find(in, out);
 	return settingTypes.find(in, out);

+ 0 - 39
src/modules/graphics/Image.h

@@ -24,8 +24,6 @@
 #include "common/config.h"
 #include "common/config.h"
 #include "common/StringMap.h"
 #include "common/StringMap.h"
 #include "common/math.h"
 #include "common/math.h"
-#include "image/ImageData.h"
-#include "image/CompressedImageData.h"
 #include "Texture.h"
 #include "Texture.h"
 
 
 namespace love
 namespace love
@@ -39,13 +37,6 @@ public:
 
 
 	static love::Type type;
 	static love::Type type;
 
 
-	enum MipmapsType
-	{
-		MIPMAPS_NONE,
-		MIPMAPS_DATA,
-		MIPMAPS_GENERATED,
-	};
-
 	enum SettingType
 	enum SettingType
 	{
 	{
 		SETTING_MIPMAPS,
 		SETTING_MIPMAPS,
@@ -61,36 +52,6 @@ public:
 		float dpiScale = 1.0f;
 		float dpiScale = 1.0f;
 	};
 	};
 
 
-	struct Slices
-	{
-	public:
-
-		Slices(TextureType textype);
-
-		void clear();
-		void set(int slice, int mipmap, love::image::ImageDataBase *data);
-		love::image::ImageDataBase *get(int slice, int mipmap) const;
-
-		void add(love::image::CompressedImageData *cdata, int startslice, int startmip, bool addallslices, bool addallmips);
-
-		int getSliceCount(int mip = 0) const;
-		int getMipmapCount(int slice = 0) const;
-
-		MipmapsType validate() const;
-
-		TextureType getTextureType() const { return textureType; }
-
-	private:
-
-		TextureType textureType;
-
-		// For 2D/Cube/2DArray texture types, each element in the data array has
-		// an array of mipmap levels. For 3D texture types, each mipmap level
-		// has an array of layers.
-		std::vector<std::vector<StrongRef<love::image::ImageDataBase>>> data;
-
-	}; // Slices
-
 	virtual ~Image();
 	virtual ~Image();
 
 
 	void replacePixels(love::image::ImageDataBase *d, int slice, int mipmap, int x, int y, bool reloadmipmaps);
 	void replacePixels(love::image::ImageDataBase *d, int slice, int mipmap, int x, int y, bool reloadmipmaps);

+ 159 - 0
src/modules/graphics/Texture.cpp

@@ -382,6 +382,165 @@ bool Texture::validateDimensions(bool throwException) const
 	return success;
 	return success;
 }
 }
 
 
+Texture::Slices::Slices(TextureType textype)
+	: textureType(textype)
+{
+}
+
+void Texture::Slices::clear()
+{
+	data.clear();
+}
+
+void Texture::Slices::set(int slice, int mipmap, love::image::ImageDataBase *d)
+{
+	if (textureType == TEXTURE_VOLUME)
+	{
+		if (mipmap >= (int) data.size())
+			data.resize(mipmap + 1);
+
+		if (slice >= (int) data[mipmap].size())
+			data[mipmap].resize(slice + 1);
+
+		data[mipmap][slice].set(d);
+	}
+	else
+	{
+		if (slice >= (int) data.size())
+			data.resize(slice + 1);
+
+		if (mipmap >= (int) data[slice].size())
+			data[slice].resize(mipmap + 1);
+
+		data[slice][mipmap].set(d);
+	}
+}
+
+love::image::ImageDataBase *Texture::Slices::get(int slice, int mipmap) const
+{
+	if (slice < 0 || slice >= getSliceCount(mipmap))
+		return nullptr;
+
+	if (mipmap < 0 || mipmap >= getMipmapCount(slice))
+		return nullptr;
+
+	if (textureType == TEXTURE_VOLUME)
+		return data[mipmap][slice].get();
+	else
+		return data[slice][mipmap].get();
+}
+
+void Texture::Slices::add(love::image::CompressedImageData *cdata, int startslice, int startmip, bool addallslices, bool addallmips)
+{
+	int slicecount = addallslices ? cdata->getSliceCount() : 1;
+	int mipcount = addallmips ? cdata->getMipmapCount() : 1;
+
+	for (int mip = 0; mip < mipcount; mip++)
+	{
+		for (int slice = 0; slice < slicecount; slice++)
+			set(startslice + slice, startmip + mip, cdata->getSlice(slice, mip));
+	}
+}
+
+int Texture::Slices::getSliceCount(int mip) const
+{
+	if (textureType == TEXTURE_VOLUME)
+	{
+		if (mip < 0 || mip >= (int) data.size())
+			return 0;
+
+		return (int) data[mip].size();
+	}
+	else
+		return (int) data.size();
+}
+
+int Texture::Slices::getMipmapCount(int slice) const
+{
+	if (textureType == TEXTURE_VOLUME)
+		return (int) data.size();
+	else
+	{
+		if (slice < 0 || slice >= (int) data.size())
+			return 0;
+
+		return data[slice].size();
+	}
+}
+
+bool Texture::Slices::validate() const
+{
+	int slicecount = getSliceCount();
+	int mipcount = getMipmapCount(0);
+
+	if (slicecount == 0 || mipcount == 0)
+		throw love::Exception("At least one ImageData or CompressedImageData is required!");
+
+	if (textureType == TEXTURE_CUBE && slicecount != 6)
+		throw love::Exception("Cube textures must have exactly 6 sides.");
+
+	image::ImageDataBase *firstdata = get(0, 0);
+
+	int w = firstdata->getWidth();
+	int h = firstdata->getHeight();
+	int depth = textureType == TEXTURE_VOLUME ? slicecount : 1;
+	PixelFormat format = firstdata->getFormat();
+
+	int expectedmips = Texture::getTotalMipmapCount(w, h, depth);
+
+	if (mipcount != expectedmips && mipcount != 1)
+		throw love::Exception("Image does not have all required mipmap levels (expected %d, got %d)", expectedmips, mipcount);
+
+	if (textureType == TEXTURE_CUBE && w != h)
+		throw love::Exception("Cube images must have equal widths and heights for each cube face.");
+
+	int mipw = w;
+	int miph = h;
+	int mipslices = slicecount;
+
+	for (int mip = 0; mip < mipcount; mip++)
+	{
+		if (textureType == TEXTURE_VOLUME)
+		{
+			slicecount = getSliceCount(mip);
+
+			if (slicecount != mipslices)
+				throw love::Exception("Invalid number of image data layers in mipmap level %d (expected %d, got %d)", mip+1, mipslices, slicecount);
+		}
+
+		for (int slice = 0; slice < slicecount; slice++)
+		{
+			auto slicedata = get(slice, mip);
+
+			if (slicedata == nullptr)
+				throw love::Exception("Missing image data (slice %d, mipmap level %d)", slice+1, mip+1);
+
+			int realw = slicedata->getWidth();
+			int realh = slicedata->getHeight();
+
+			if (getMipmapCount(slice) != mipcount)
+				throw love::Exception("All Image layers must have the same mipmap count.");
+
+			if (mipw != realw)
+				throw love::Exception("Width of image data (slice %d, mipmap level %d) is incorrect (expected %d, got %d)", slice+1, mip+1, mipw, realw);
+
+			if (miph != realh)
+				throw love::Exception("Height of image data (slice %d, mipmap level %d) is incorrect (expected %d, got %d)", slice+1, mip+1, miph, realh);
+
+			if (format != slicedata->getFormat())
+				throw love::Exception("All Image slices and mipmaps must have the same pixel format.");
+		}
+
+		mipw = std::max(mipw / 2, 1);
+		miph = std::max(miph / 2, 1);
+
+		if (textureType == TEXTURE_VOLUME)
+			mipslices = std::max(mipslices / 2, 1);
+	}
+
+	return true;
+}
+
 bool Texture::getConstant(const char *in, TextureType &out)
 bool Texture::getConstant(const char *in, TextureType &out)
 {
 {
 	return texTypes.find(in, out);
 	return texTypes.find(in, out);

+ 39 - 0
src/modules/graphics/Texture.h

@@ -33,6 +33,8 @@
 #include "vertex.h"
 #include "vertex.h"
 #include "renderstate.h"
 #include "renderstate.h"
 #include "Resource.h"
 #include "Resource.h"
+#include "image/ImageData.h"
+#include "image/CompressedImageData.h"
 
 
 // C
 // C
 #include <stddef.h>
 #include <stddef.h>
@@ -96,6 +98,43 @@ public:
 		WrapMode r = WRAP_CLAMP;
 		WrapMode r = WRAP_CLAMP;
 	};
 	};
 
 
+	enum MipmapsType
+	{
+		MIPMAPS_NONE,
+		MIPMAPS_DATA,
+		MIPMAPS_GENERATED,
+	};
+
+	struct Slices
+	{
+	public:
+
+		Slices(TextureType textype);
+
+		void clear();
+		void set(int slice, int mipmap, love::image::ImageDataBase *data);
+		love::image::ImageDataBase *get(int slice, int mipmap) const;
+
+		void add(love::image::CompressedImageData *cdata, int startslice, int startmip, bool addallslices, bool addallmips);
+
+		int getSliceCount(int mip = 0) const;
+		int getMipmapCount(int slice = 0) const;
+
+		bool validate() const;
+
+		TextureType getTextureType() const { return textureType; }
+
+	private:
+
+		TextureType textureType;
+
+		// For 2D/Cube/2DArray texture types, each element in the data array has
+		// an array of mipmap levels. For 3D texture types, each mipmap level
+		// has an array of layers.
+		std::vector<std::vector<StrongRef<love::image::ImageDataBase>>> data;
+
+	}; // Slices
+
 	static Filter defaultFilter;
 	static Filter defaultFilter;
 	static FilterMode defaultMipmapFilter;
 	static FilterMode defaultMipmapFilter;
 	static float defaultMipmapSharpness;
 	static float defaultMipmapSharpness;

+ 1 - 1
src/modules/graphics/opengl/Graphics.cpp

@@ -130,7 +130,7 @@ love::graphics::StreamBuffer *Graphics::newStreamBuffer(BufferType type, size_t
 	return CreateStreamBuffer(type, size);
 	return CreateStreamBuffer(type, size);
 }
 }
 
 
-love::graphics::Image *Graphics::newImage(const Image::Slices &data, const Image::Settings &settings)
+love::graphics::Image *Graphics::newImage(const Texture::Slices &data, const Image::Settings &settings)
 {
 {
 	return new Image(data, settings);
 	return new Image(data, settings);
 }
 }

+ 1 - 1
src/modules/graphics/opengl/Graphics.h

@@ -60,7 +60,7 @@ public:
 	// Implements Module.
 	// Implements Module.
 	const char *getName() const override;
 	const char *getName() const override;
 
 
-	love::graphics::Image *newImage(const Image::Slices &data, const Image::Settings &settings) override;
+	love::graphics::Image *newImage(const Texture::Slices &data, const Image::Settings &settings) override;
 	love::graphics::Image *newImage(TextureType textype, PixelFormat format, int width, int height, int slices, const Image::Settings &settings) override;
 	love::graphics::Image *newImage(TextureType textype, PixelFormat format, int width, int height, int slices, const Image::Settings &settings) override;
 	love::graphics::Canvas *newCanvas(const Canvas::Settings &settings) override;
 	love::graphics::Canvas *newCanvas(const Canvas::Settings &settings) override;
 	love::graphics::Buffer *newBuffer(size_t size, const void *data, BufferType type, vertex::Usage usage, uint32 mapflags) override;
 	love::graphics::Buffer *newBuffer(size_t size, const void *data, BufferType type, vertex::Usage usage, uint32 mapflags) override;

+ 5 - 5
src/modules/graphics/wrap_Graphics.cpp

@@ -757,7 +757,7 @@ getImageData(lua_State *L, int idx, bool allowcompressed, float *dpiscale)
 	return std::make_pair(idata, cdata);
 	return std::make_pair(idata, cdata);
 }
 }
 
 
-static int w__pushNewImage(lua_State *L, Image::Slices &slices, const Image::Settings &settings)
+static int w__pushNewImage(lua_State *L, Texture::Slices &slices, const Image::Settings &settings)
 {
 {
 	StrongRef<Image> i;
 	StrongRef<Image> i;
 	luax_catchexcept(L,
 	luax_catchexcept(L,
@@ -773,7 +773,7 @@ int w_newCubeImage(lua_State *L)
 {
 {
 	luax_checkgraphicscreated(L);
 	luax_checkgraphicscreated(L);
 
 
-	Image::Slices slices(TEXTURE_CUBE);
+	Texture::Slices slices(TEXTURE_CUBE);
 
 
 	bool dpiscaleset = false;
 	bool dpiscaleset = false;
 	Image::Settings settings = w__optImageSettings(L, 2, dpiscaleset);
 	Image::Settings settings = w__optImageSettings(L, 2, dpiscaleset);
@@ -867,7 +867,7 @@ int w_newArrayImage(lua_State *L)
 {
 {
 	luax_checkgraphicscreated(L);
 	luax_checkgraphicscreated(L);
 
 
-	Image::Slices slices(TEXTURE_2D_ARRAY);
+	Texture::Slices slices(TEXTURE_2D_ARRAY);
 
 
 	bool dpiscaleset = false;
 	bool dpiscaleset = false;
 	Image::Settings settings = w__optImageSettings(L, 2, dpiscaleset);
 	Image::Settings settings = w__optImageSettings(L, 2, dpiscaleset);
@@ -933,7 +933,7 @@ int w_newVolumeImage(lua_State *L)
 
 
 	auto imagemodule = Module::getInstance<love::image::Image>(Module::M_IMAGE);
 	auto imagemodule = Module::getInstance<love::image::Image>(Module::M_IMAGE);
 
 
-	Image::Slices slices(TEXTURE_VOLUME);
+	Texture::Slices slices(TEXTURE_VOLUME);
 
 
 	bool dpiscaleset = false;
 	bool dpiscaleset = false;
 	Image::Settings settings = w__optImageSettings(L, 2, dpiscaleset);
 	Image::Settings settings = w__optImageSettings(L, 2, dpiscaleset);
@@ -1004,7 +1004,7 @@ int w_newImage(lua_State *L)
 {
 {
 	luax_checkgraphicscreated(L);
 	luax_checkgraphicscreated(L);
 
 
-	Image::Slices slices(TEXTURE_2D);
+	Texture::Slices slices(TEXTURE_2D);
 
 
 	bool dpiscaleset = false;
 	bool dpiscaleset = false;
 	Image::Settings settings = w__optImageSettings(L, 2, dpiscaleset);
 	Image::Settings settings = w__optImageSettings(L, 2, dpiscaleset);