Browse Source

Added Image:refresh(), reloads a love.graphics image using the imagedata that created it

Alex Szpakowski 12 years ago
parent
commit
b22f1aa16a

+ 55 - 18
src/modules/graphics/opengl/Image.cpp

@@ -169,14 +169,14 @@ void Image::createMipmaps()
 		// 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);
@@ -186,14 +186,14 @@ void Image::createMipmaps()
 	{
 		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());
 	}
 }
 
@@ -378,8 +378,7 @@ bool Image::loadVolatilePOT()
 
 		glTexSubImage2D(GL_TEXTURE_2D,
 		                0,
-		                0,
-		                0,
+		                0, 0,
 		                (GLsizei)width,
 		                (GLsizei)height,
 		                GL_RGBA,
@@ -454,6 +453,44 @@ void Image::unloadVolatile()
 	}
 }
 
+bool Image::refresh()
+{
+	// No effect if the texture hasn't been created yet.
+	if (texture == 0)
+		return false;
+
+	bind();
+
+	if (isCompressed() && cdata)
+	{
+		GLenum format = getCompressedFormat(cdata->getType());
+		glCompressedTexSubImage2DARB(GL_TEXTURE_2D,
+		                             0,
+								     0, 0,
+		                             cdata->getWidth(0),
+		                             cdata->getHeight(0),
+		                             format,
+		                             GLsizei(cdata->getSize(0)),
+		                             cdata->getData(0));
+	}
+	else if (data)
+	{
+		glTexSubImage2D(GL_TEXTURE_2D,
+		                0,
+		                0, 0,
+		                (GLsizei)width,
+		                (GLsizei)height,
+		                GL_RGBA,
+		                GL_UNSIGNED_BYTE,
+		                data->getData());
+	}
+
+	mipmapsCreated = false;
+	checkMipmapsCreated();
+
+	return true;
+}
+
 void Image::drawv(const Matrix &t, const vertex *v) const
 {
 	bind();

+ 7 - 0
src/modules/graphics/opengl/Image.h

@@ -115,6 +115,13 @@ public:
 	bool loadVolatile();
 	void unloadVolatile();
 
+	/**
+	 * Re-uploads the ImageData or CompressedData associated with this Image to
+	 * the GPU, allowing situations where lovers modify an ImageData after image
+	 * creation from the ImageData, and apply the changes with Image:refresh().
+	 **/
+	bool refresh();
+
 	static void setDefaultMipmapSharpness(float sharpness);
 	static float getDefaultMipmapSharpness();
 	static void setDefaultMipmapFilter(FilterMode f);

+ 15 - 0
src/modules/graphics/opengl/wrap_Image.cpp

@@ -182,6 +182,20 @@ int w_Image_isCompressed(lua_State *L)
 	return 1;
 }
 
+int w_Image_refresh(lua_State *L)
+{
+	Image *i = luax_checkimage(L, 1);
+	try
+	{
+		i->refresh();
+	}
+	catch (love::Exception &e)
+	{
+		return luaL_error(L, "%s", e.what());
+	}
+	return 0;
+}
+
 static const luaL_Reg functions[] =
 {
 	{ "getWidth", w_Image_getWidth },
@@ -194,6 +208,7 @@ static const luaL_Reg functions[] =
 	{ "setMipmapFilter", w_Image_setMipmapFilter },
 	{ "getMipmapFilter", w_Image_getMipmapFilter },
 	{ "isCompressed", w_Image_isCompressed },
+	{ "refresh", w_Image_refresh },
 	{ 0, 0 }
 };
 

+ 1 - 0
src/modules/graphics/opengl/wrap_Image.h

@@ -43,6 +43,7 @@ int w_Image_getMipmapFilter(lua_State *L);
 int w_Image_setWrap(lua_State *L);
 int w_Image_getWrap(lua_State *L);
 int w_Image_isCompressed(lua_State *L);
+int w_Image_refresh(lua_State *L);
 extern "C" int luaopen_image(lua_State *L);
 
 } // opengl