mirror of
https://github.com/love2d/love.git
synced 2026-08-19 12:14:20 +02:00
Removed Canvas:getPixel and added optional x/y/width/height arguments to Canvas:getImageData to specify a sub-rectangle (see issue #1001.)
--HG-- branch : minor
This commit is contained in:
@@ -955,13 +955,24 @@ bool Canvas::checkCreateStencil()
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
love::image::ImageData *Canvas::getImageData(love::image::Image *image)
|
love::image::ImageData *Canvas::getImageData(love::image::Image *image, int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
|
if (x < 0 || y < 0 || w <= 0 || h <= 0 || (x + w) > width || (y + h) > height)
|
||||||
|
throw love::Exception("Invalid ImageData rectangle dimensions.");
|
||||||
|
|
||||||
resolveMSAA();
|
resolveMSAA();
|
||||||
|
|
||||||
int row = 4 * width;
|
int row = 4 * w;
|
||||||
int size = row * height;
|
int size = row * h;
|
||||||
GLubyte *pixels = new GLubyte[size];
|
GLubyte *pixels = nullptr;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pixels = new GLubyte[size];
|
||||||
|
}
|
||||||
|
catch (std::bad_alloc &)
|
||||||
|
{
|
||||||
|
throw love::Exception("Out of memory.");
|
||||||
|
}
|
||||||
|
|
||||||
// Our texture is attached to 'resolve_fbo' when we use MSAA.
|
// Our texture is attached to 'resolve_fbo' when we use MSAA.
|
||||||
if (resolve_fbo != 0 && (GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object))
|
if (resolve_fbo != 0 && (GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object))
|
||||||
@@ -971,7 +982,7 @@ love::image::ImageData *Canvas::getImageData(love::image::Image *image)
|
|||||||
else
|
else
|
||||||
strategy->bindFBO(fbo);
|
strategy->bindFBO(fbo);
|
||||||
|
|
||||||
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||||
|
|
||||||
if (current)
|
if (current)
|
||||||
strategy->bindFBO(current->fbo);
|
strategy->bindFBO(current->fbo);
|
||||||
@@ -979,31 +990,7 @@ love::image::ImageData *Canvas::getImageData(love::image::Image *image)
|
|||||||
strategy->bindFBO(gl.getDefaultFBO());
|
strategy->bindFBO(gl.getDefaultFBO());
|
||||||
|
|
||||||
// The new ImageData now owns the pixel data, so we don't delete it here.
|
// The new ImageData now owns the pixel data, so we don't delete it here.
|
||||||
love::image::ImageData *img = image->newImageData(width, height, (void *)pixels, true);
|
return image->newImageData(w, h, pixels, true);
|
||||||
return img;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Canvas::getPixel(unsigned char* pixel_rgba, int x, int y)
|
|
||||||
{
|
|
||||||
if (x < 0 || x >= width || y < 0 || y >= width)
|
|
||||||
throw love::Exception("Attempt to get out-of-range pixel (%d,%d)!", x, y);
|
|
||||||
|
|
||||||
resolveMSAA();
|
|
||||||
|
|
||||||
// Our texture is attached to 'resolve_fbo' when we use MSAA.
|
|
||||||
if (resolve_fbo != 0 && (GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object))
|
|
||||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, resolve_fbo);
|
|
||||||
else if (resolve_fbo != 0 && GLAD_EXT_framebuffer_multisample)
|
|
||||||
glBindFramebufferEXT(GL_READ_FRAMEBUFFER, resolve_fbo);
|
|
||||||
else if (current != this)
|
|
||||||
strategy->bindFBO(fbo);
|
|
||||||
|
|
||||||
glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel_rgba);
|
|
||||||
|
|
||||||
if (current && current != this)
|
|
||||||
strategy->bindFBO(current->fbo);
|
|
||||||
else if (!current)
|
|
||||||
strategy->bindFBO(gl.getDefaultFBO());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Canvas::resolveMSAA()
|
bool Canvas::resolveMSAA()
|
||||||
|
|||||||
@@ -91,9 +91,7 @@ public:
|
|||||||
**/
|
**/
|
||||||
bool checkCreateStencil();
|
bool checkCreateStencil();
|
||||||
|
|
||||||
love::image::ImageData *getImageData(love::image::Image *image);
|
love::image::ImageData *getImageData(love::image::Image *image, int x, int y, int w, int h);
|
||||||
|
|
||||||
void getPixel(unsigned char* pixel_rgba, int x, int y);
|
|
||||||
|
|
||||||
inline const std::vector<Canvas *> &getAttachedCanvases() const
|
inline const std::vector<Canvas *> &getAttachedCanvases() const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -66,28 +66,17 @@ int w_Canvas_getImageData(lua_State *L)
|
|||||||
{
|
{
|
||||||
Canvas *canvas = luax_checkcanvas(L, 1);
|
Canvas *canvas = luax_checkcanvas(L, 1);
|
||||||
love::image::Image *image = luax_getmodule<love::image::Image>(L, "image", MODULE_IMAGE_T);
|
love::image::Image *image = luax_getmodule<love::image::Image>(L, "image", MODULE_IMAGE_T);
|
||||||
love::image::ImageData *img = canvas->getImageData(image);
|
int x = luaL_optint(L, 2, 0);
|
||||||
|
int y = luaL_optint(L, 3, 0);
|
||||||
|
int w = luaL_optint(L, 4, canvas->getWidth());
|
||||||
|
int h = luaL_optint(L, 5, canvas->getHeight());
|
||||||
|
|
||||||
|
love::image::ImageData *img = canvas->getImageData(image, x, y, w, h);
|
||||||
luax_pushtype(L, "ImageData", IMAGE_IMAGE_DATA_T, img);
|
luax_pushtype(L, "ImageData", IMAGE_IMAGE_DATA_T, img);
|
||||||
img->release();
|
img->release();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int w_Canvas_getPixel(lua_State * L)
|
|
||||||
{
|
|
||||||
Canvas * canvas = luax_checkcanvas(L, 1);
|
|
||||||
int x = luaL_checkint(L, 2);
|
|
||||||
int y = luaL_checkint(L, 3);
|
|
||||||
unsigned char c[4];
|
|
||||||
|
|
||||||
luax_catchexcept(L, [&](){ canvas->getPixel(c, x, y); });
|
|
||||||
|
|
||||||
lua_pushnumber(L, c[0]);
|
|
||||||
lua_pushnumber(L, c[1]);
|
|
||||||
lua_pushnumber(L, c[2]);
|
|
||||||
lua_pushnumber(L, c[3]);
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
int w_Canvas_clear(lua_State *L)
|
int w_Canvas_clear(lua_State *L)
|
||||||
{
|
{
|
||||||
Canvas *canvas = luax_checkcanvas(L, 1);
|
Canvas *canvas = luax_checkcanvas(L, 1);
|
||||||
@@ -152,7 +141,6 @@ static const luaL_Reg functions[] =
|
|||||||
|
|
||||||
{ "renderTo", w_Canvas_renderTo },
|
{ "renderTo", w_Canvas_renderTo },
|
||||||
{ "getImageData", w_Canvas_getImageData },
|
{ "getImageData", w_Canvas_getImageData },
|
||||||
{ "getPixel", w_Canvas_getPixel },
|
|
||||||
{ "clear", w_Canvas_clear },
|
{ "clear", w_Canvas_clear },
|
||||||
{ "getFormat", w_Canvas_getFormat },
|
{ "getFormat", w_Canvas_getFormat },
|
||||||
{ "getMSAA", w_Canvas_getMSAA },
|
{ "getMSAA", w_Canvas_getMSAA },
|
||||||
|
|||||||
Reference in New Issue
Block a user