Commits

Alex Szpakowski committed aa603d1

Code cleanup

Comments (0)

Files changed (11)

src/libraries/ddsparse/ddsparse.cpp

 		// Data must be big enough for both headers plus the magic value.
 		if (dataSize < (sizeof(uint32_t) + sizeof(DDSHeader) + sizeof(DDSHeader10)))
 			return false;
-
 	}
 
 	return true;
 		if ((options & OPTIONS_COPY_DATA) && img.dataSize > 0)
 		{
 			uint8_t *data = 0;
-
 			try
 			{
 				data = new uint8_t[img.dataSize];
 				clearData();
 				throw;
 			}
-
+			memcpy(data, it->data, img.dataSize);
 			img.data = data;
 		}
 
 		else if (fmt.fourCC == FourCC('D','X','T','5'))
 			return FORMAT_DXT5;
 		else if (fmt.fourCC == FourCC('A','T','I','2'))
-			return FORMAT_BC5u;
+			return FORMAT_BC5;
+		else if (fmt.fourCC == FourCC('B','C','5','S'))
+			return FORMAT_BC5s;
 	}
 
 	return FORMAT_UNKNOWN;
 		break;
 	case DXGI_FORMAT_BC5_TYPELESS:
 	case DXGI_FORMAT_BC5_UNORM:
-		f = FORMAT_BC5u;
+		f = FORMAT_BC5;
 		break;
 	case DXGI_FORMAT_BC7_TYPELESS:
 	case DXGI_FORMAT_BC7_UNORM:
 	case FORMAT_DXT3:
 	case FORMAT_DXT5:
 	case FORMAT_BC5s:
-	case FORMAT_BC5u:
+	case FORMAT_BC5:
 	case FORMAT_BC7:
 	case FORMAT_BC7srgb:
 		{
 		if (options & OPTIONS_COPY_DATA)
 		{
 			uint8_t *newData = 0;
-
 			try
 			{
 				newData = new uint8_t[img.dataSize];
 				clearData();
 				throw;
 			}
-
 			memcpy(newData, &data[offset], img.dataSize);
 			img.data = newData;
 		}

src/libraries/ddsparse/ddsparse.h

 	FORMAT_DXT3,
 	FORMAT_DXT5,
 	FORMAT_BC5s,    // Signed.
-	FORMAT_BC5u,    // Unsigned.
+	FORMAT_BC5,     // Unsigned.
 	FORMAT_BC7,
 	FORMAT_BC7srgb, // sRGB color space.
 	FORMAT_UNKNOWN

src/modules/graphics/opengl/Graphics.cpp

 
 void Graphics::setIcon(Image *image)
 {
-	currentWindow->setIcon(image->getData());
+	love::image::ImageData *data = image->getData();
+	if (data)
+		currentWindow->setIcon(data);
+	else
+		throw love::Exception("Cannot use compressed image data to set an icon.");
 }
 
 void Graphics::setCaption(const char *caption)

src/modules/graphics/opengl/Image.cpp

 #include <cstring> // For memcpy
 #include <algorithm> // for min/max
 
-#include <iostream>
-
 namespace love
 {
 namespace graphics
 	drawv(t, v);
 }
 
-void Image::checkMipmapsCreated()
+void Image::uploadCompressedMipmaps()
 {
-	if (mipmapsCreated || (filter.mipmap != FILTER_NEAREST && filter.mipmap != FILTER_LINEAR))
+	if (!isCompressed || !cdata || !hasCompressedTextureSupport(cdata->getType()))
 		return;
 
-	if (!(isCompressed && cdata) && !hasMipmapSupport())
-		throw love::Exception("Mipmap filtering is not supported on this system.");
-
-	// Some old drivers claim support for NPOT textures, but fail when creating mipmaps.
-	// we can't detect which systems will do this, so we fail gracefully for all NPOT images.
-	int w = int(width), h = int(height);
-	if (!isCompressed && (w != next_p2(w) || h != next_p2(h)))
-		throw love::Exception("Cannot create mipmaps: image does not have power of two dimensions.");
-
 	bind();
 
-	if (isCompressed && cdata && hasCompressedTextureSupport(cdata->getType()))
+	int numMipmaps = cdata->getNumMipmaps();
+
+	// We have to inform OpenGL if the image doesn't have all mipmap levels.
+	if (GLEE_VERSION_1_2 || GLEE_SGIS_texture_lod)
 	{
-		int numMipmaps = cdata->getNumMipmaps();
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, numMipmaps - 1);
+	}
+	else if (cdata->getWidth(numMipmaps-1) > 1 || cdata->getHeight(numMipmaps-1) > 1)
+	{
+		// Telling OpenGL to ignore certain levels isn't always supported.
+		throw love::Exception("Cannot load mipmaps: "
+		      "compressed image does not have all required levels.");
+	}
 
-		// We have to inform OpenGL if the image doesn't have all mipmap levels.
-		if (GLEE_VERSION_1_2 || GLEE_SGIS_texture_lod)
-			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, numMipmaps - 1);
-		else if (cdata->getWidth(numMipmaps-1) > 1 || cdata->getHeight(numMipmaps-1) > 1)
-		{
-			// Telling OpenGL to ignore certain levels isn't always supported.
-			throw love::Exception("Cannot load mipmaps: "
-								  "compressed image does not have all required levels.");
-		}
+	for (int i = 1; i < numMipmaps; i++)
+	{
+		glCompressedTexImage2DARB(GL_TEXTURE_2D,
+		                          i,
+		                          getCompressedFormat(cdata->getType()),
+		                          cdata->getWidth(i),
+		                          cdata->getHeight(i),
+		                          0,
+		                          GLsizei(cdata->getSize(i)),
+		                          cdata->getData(i));
+	}
+}
 
-		GLenum format = getCompressedFormat(cdata->getType());
+void Image::createMipmaps()
+{
+	if (!data)
+		return;
 
-		for (int i = 1; i < numMipmaps; i++)
-		{
-			glCompressedTexImage2DARB(GL_TEXTURE_2D,
-			                          i,
-			                          format,
-			                          cdata->getWidth(i),
-			                          cdata->getHeight(i),
-			                          0,
-			                          GLsizei(cdata->getSize(i)),
-			                          cdata->getData(i));
-		}
+	if (!hasMipmapSupport())
+		throw love::Exception("Mipmap filtering is not supported on this system.");
+
+	// Some old drivers claim support for NPOT textures, but fail when creating
+	// mipmaps. We can't detect which systems will do this, so we fail gracefully
+	// for all NPOT images.
+	int w = int(width), h = int(height);
+	if (w != next_p2(w) || h != next_p2(h))
+	{
+		throw love::Exception("Cannot create mipmaps: "
+		      "image does not have power of two dimensions.");
 	}
-	else if (data && hasNpot() && (GLEE_VERSION_3_0 || GLEE_ARB_framebuffer_object))
+
+	bind();
+
+	if (hasNpot() && (GLEE_VERSION_3_0 || GLEE_ARB_framebuffer_object))
 	{
 		// AMD/ATI drivers have several bugs when generating mipmaps,
 		// re-uploading the entire base image seems to be required.
 		glTexImage2D(GL_TEXTURE_2D,
-		             0,
-		             GL_RGBA8,
-		             (GLsizei)width,
-		             (GLsizei)height,
-		             0,
-		             GL_RGBA,
-		             GL_UNSIGNED_BYTE,
-		             data->getData());
+					 0,
+					 GL_RGBA8,
+					 (GLsizei)width,
+					 (GLsizei)height,
+					 0,
+					 GL_RGBA,
+					 GL_UNSIGNED_BYTE,
+					 data->getData());
 
 		// More bugs: http://www.opengl.org/wiki/Common_Mistakes#Automatic_mipmap_generation
 		glEnable(GL_TEXTURE_2D);
 		glGenerateMipmap(GL_TEXTURE_2D);
 	}
-	else if (data)
+	else
 	{
 		glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
 		glTexSubImage2D(GL_TEXTURE_2D,
-		                0,
-		                0,
-		                0,
-		                (GLsizei)width,
-		                (GLsizei)height,
-		                GL_RGBA,
-		                GL_UNSIGNED_BYTE,
-		                data->getData());
+						0,
+						0,
+						0,
+						(GLsizei)width,
+						(GLsizei)height,
+						GL_RGBA,
+						GL_UNSIGNED_BYTE,
+						data->getData());
 	}
+}
+
+void Image::checkMipmapsCreated()
+{
+	if (mipmapsCreated || filter.mipmap == FILTER_NONE)
+		return;
+
+	if (isCompressed && cdata && hasCompressedTextureSupport(cdata->getType()))
+		uploadCompressedMipmaps();
+	else if (data)
+		createMipmaps();
 	else
 		return;
 
 		mipmapSharpness = std::min(std::max(sharpness, -maxMipmapSharpness + 0.01f), maxMipmapSharpness - 0.01f);
 
 		bind();
-		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -mipmapSharpness); // negative bias is sharper
+
+		// negative bias is sharper
+		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -mipmapSharpness);
 	}
 	else
 		mipmapSharpness = 0.0f;
 		if (image::CompressedData::getConstant(cdata->getType(), str))
 		{
 			throw love::Exception("Cannot create image: "
-								  "%s compressed images are not supported on this system.", str);
+			      "%s compressed images are not supported on this system.", str);
 		}
 		else
 			throw love::Exception("cannot create image: format is not supported on this system.");
 
 	if (isCompressed && cdata)
 	{
-		if (s != 1.0f || t != 1.0f)
+		if (s < 1.0f || t < 1.0f)
 		{
 			throw love::Exception("Cannot create image: "
-								  "NPOT compressed images are not supported on this system.");
+				  "compressed NPOT images are not supported on this system.");
 		}
 
-		GLenum format = getCompressedFormat(cdata->getType());
-
 		glCompressedTexImage2DARB(GL_TEXTURE_2D,
 		                          0,
-		                          format,
+		                          getCompressedFormat(cdata->getType()),
 		                          cdata->getWidth(0),
 		                          cdata->getHeight(0),
 		                          0,
 		return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
 	case image::CompressedData::TYPE_BC5s:
 		return GL_COMPRESSED_SIGNED_RG_RGTC2;
-	case image::CompressedData::TYPE_BC5u:
+	case image::CompressedData::TYPE_BC5:
 		return GL_COMPRESSED_RG_RGTC2;
 	case image::CompressedData::TYPE_BC7:
 		return GL_COMPRESSED_RGBA_BPTC_UNORM_ARB;
 		return GLEE_EXT_texture_compression_s3tc;
 
 	case image::CompressedData::TYPE_BC5s:
-	case image::CompressedData::TYPE_BC5u:
-		return (GLEE_VERSION_3_0 || GLEE_ARB_texture_compression_rgtc);
+	case image::CompressedData::TYPE_BC5:
+		return (GLEE_VERSION_3_0 || GLEE_ARB_texture_compression_rgtc || GLEE_EXT_texture_compression_rgtc);
 
 	case image::CompressedData::TYPE_BC7:
 	case image::CompressedData::TYPE_BC7srgb:

src/modules/graphics/opengl/Image.h

 	bool loadVolatilePOT();
 	bool loadVolatileNPOT();
 
+	void uploadCompressedMipmaps();
+	void createMipmaps();
 	void checkMipmapsCreated();
 
 	static float maxMipmapSharpness;

src/modules/graphics/opengl/wrap_Graphics.cpp

 int w_setIcon(lua_State *L)
 {
 	Image *image = luax_checktype<Image>(L, 1, "Image", GRAPHICS_IMAGE_T);
-	instance->setIcon(image);
+	try
+	{
+		instance->setIcon(image);
+	}
+	catch (love::Exception &e)
+	{
+		return luaL_error(L, "%s", e.what());
+	}
 	return 0;
 }
 
 				supported = false;
 			break;
 		case Graphics::SUPPORT_BC5:
-			if (!Image::hasCompressedTextureSupport(image::CompressedData::TYPE_BC5u))
+			if (!Image::hasCompressedTextureSupport(image::CompressedData::TYPE_BC5))
 				supported = false;
 			break;
 		case Graphics::SUPPORT_BC7:

src/modules/image/CompressedData.cpp

 	{"dxt3", CompressedData::TYPE_DXT3},
 	{"dxt5", CompressedData::TYPE_DXT5},
 	{"bc5s", CompressedData::TYPE_BC5s},
-	{"bc5u", CompressedData::TYPE_BC5u},
+	{"bc5", CompressedData::TYPE_BC5},
 	{"bc7", CompressedData::TYPE_BC7},
 	{"bc7srgb", CompressedData::TYPE_BC7srgb},
 };

src/modules/image/CompressedData.h

 namespace image
 {
 
-// 
+// CompressedData represents image data which is designed to be uploaded to the
+// GPU and rendered in its compressed form, without being un-compressed.
+// http://renderingpipeline.com/2012/07/texture-compression/
+
 class CompressedData : public Data
 {
 public:
 
-	// 
+	// Types of compressed image data.
 	enum TextureType
 	{
 		TYPE_DXT1,
 		TYPE_DXT3,
 		TYPE_DXT5,
 		TYPE_BC5s,
-		TYPE_BC5u,
+		TYPE_BC5,
 		TYPE_BC7,
 		TYPE_BC7srgb,
 		TYPE_MAX_ENUM

src/modules/image/Image.h

 	virtual ImageData *newImageData(int width, int height, void *data) = 0;
 
 	/**
-	 *
+	 * Creates new CompressedData from a file.
+	 * @param file The file containing the compressed image data.
+	 * @return The new CompressedData.
 	 **/
 	virtual CompressedData *newCompressedData(love::filesystem::File *file) = 0;
 
 	/**
-	 *
+	 * Creates new CompressedData from a raw Data.
+	 * @param data The object containing the compressed image data.
+	 * @return The new CompressedData.
 	 **/
 	virtual CompressedData *newCompressedData(Data *data) = 0;
 
 	/**
-	 *
+	 * Determines whether a File is Compressed image data or not.
+	 * @param file The file to test.
 	 **/
 	virtual bool isCompressed(love::filesystem::File *file) = 0;
 
 	/**
-	 *
+	 * Determines whether a raw Data is Compressed image data or not.
+	 * @param data The data to test.
 	 **/
 	virtual bool isCompressed(Data *data) = 0;
 

src/modules/image/devil/CompressedData.cpp

 	case dds::FORMAT_BC5s:
 		type = TYPE_BC5s;
 		break;
-	case dds::FORMAT_BC5u:
-		type = TYPE_BC5u;
+	case dds::FORMAT_BC5:
+		type = TYPE_BC5;
 		break;
 	case dds::FORMAT_BC7:
 		type = TYPE_BC7;

src/modules/image/devil/Image.cpp

 
 	// Check whether the actual data is compressed.
 	Data *data = file->read();
-	bool compressed = CompressedData::isCompressed(data);
+	bool compressed = isCompressed(data);
 	data->release();
 
 	return compressed;