diff --git a/src/modules/graphics/opengl/Image.cpp b/src/modules/graphics/opengl/Image.cpp index 7a7143447..47887e7ca 100644 --- a/src/modules/graphics/opengl/Image.cpp +++ b/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(); diff --git a/src/modules/graphics/opengl/Image.h b/src/modules/graphics/opengl/Image.h index 6b3d5543f..6631a9ef0 100644 --- a/src/modules/graphics/opengl/Image.h +++ b/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); diff --git a/src/modules/graphics/opengl/wrap_Image.cpp b/src/modules/graphics/opengl/wrap_Image.cpp index dc541db74..2f1788c17 100644 --- a/src/modules/graphics/opengl/wrap_Image.cpp +++ b/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 } }; diff --git a/src/modules/graphics/opengl/wrap_Image.h b/src/modules/graphics/opengl/wrap_Image.h index d81a623c2..44ba00fe6 100644 --- a/src/modules/graphics/opengl/wrap_Image.h +++ b/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