Render pass API. Replaces love.graphics.setCanvas and friends.

- Removed love.graphics.set/getCanvas, Canvas:renderTo, Canvas:newImageData, love.graphics.clear, love.graphics.discard, and love.graphics.newScreenshot.

- Added love.graphics.beginPass and love.graphics.endPass. All rendering must happen within a pass. love.draw is now called while a render pass to the main screen is active.
- Added love.graphics.renderPass, which is a wrapper for begin/endPass which calls the supplied function argument in between a begin/end. This is similar to the old Canvas:renderTo.
- Added love.graphics.isPassActive, getPassCanvases, getPassWidth, getPassHeight, and getPassDimensions.
- Added love.graphics.captureScreenshot.

- Added a new love.run callback love.drawpasses, which is called after love.update and before love.draw. It is the place to render to Canvases using beginPass or renderPass, since love.draw now always draws to the main screen.

- Renamed the ‘canvasswitches’ field in the table returned by love.graphics.getStats to ‘renderpasses’.

love.graphics.beginPass has the following variants (and renderPass mirrors them with an additional function argument at the end):

- love.graphics.beginPass(), begins rendering to the main screen without clearing it.
- love.graphics.beginPass(r, g, b [, a]), begins rendering to the main screen and clears the screen to the specified color.

- love.graphics.beginPass(canvas [, willstencil]), begins rendering to the specified Canvas without clearing it. love.graphics.stencil can only be used within the Canvas if ‘willstencil’ is true.
- love.graphics.beginPass(canvas, r, g, b [, a] [, willstencil]), beings rendering to the specified Canvas and clears it to the specified color. love.graphics.stencil can only be used within the Canvas if ‘willstencil’ is true.

- love.graphics.beginPass(info), where ‘info’ is a table in the following form:
{
    {canvas [, r, g, b, a]}, — A canvas and an optional color to clear the Canvas to when the pass begins.
    {canvas2, [r, g, b, a]}, — Additional Canvases and optional clear colors for multi-canvas rendering.
    …,
    stencil = false, — Optional boolean field to specify whether love.graphics.stencil is allowed within this pass. False by default.
}

The pass info table can be created once up-front and used for multiple beginPass/renderPass calls.

love.graphics.endPass can take an optional callback function argument, which causes endPass to capture the contents of the Canvas drawn to in the render pass to a new ImageData and passes it to the supplied function (this replaces Canvas:newImageData). This does not work on the main screen.

love.graphics.captureScreenshot replaces love.graphics.newScreenshot. It takes a callback function argument which causes love.graphics.present to capture the contents of the screen to a new ImageData and passes it to the supplied function. captureScreenshot can only be called before drawing to the main screen begins in the current frame (e.g. in love.keypressed, love.update, etc.)

--HG--
branch : minor
This commit is contained in:
Alex Szpakowski
2016-11-19 19:13:26 -04:00
parent aeca14a35a
commit 3e80ec2257
24 changed files with 2562 additions and 1123 deletions
+17
View File
@@ -112,6 +112,8 @@ Event::~Event()
void Event::pump()
{
exceptionIfInRenderPass();
SDL_Event e;
while (SDL_PollEvent(&e))
@@ -127,6 +129,8 @@ void Event::pump()
Message *Event::wait()
{
exceptionIfInRenderPass();
SDL_Event e;
if (SDL_WaitEvent(&e) != 1)
@@ -137,6 +141,8 @@ Message *Event::wait()
void Event::clear()
{
exceptionIfInRenderPass();
SDL_Event e;
while (SDL_PollEvent(&e))
@@ -147,6 +153,17 @@ void Event::clear()
love::event::Event::clear();
}
void Event::exceptionIfInRenderPass()
{
// Some core OS graphics functionality (e.g. swap buffers on some platforms)
// happens inside SDL_PumpEvents - which is called by SDL_PollEvent and
// friends. It's probably a bad idea to call those functions while we're in
// a render pass.
auto gfx = Module::getInstance<graphics::Graphics>(Module::M_GRAPHICS);
if (gfx != nullptr && gfx->isPassActive())
throw love::Exception("Cannot call this function while a render pass is active in love.graphics.");
}
Message *Event::convert(const SDL_Event &e) const
{
Message *msg = nullptr;
+2
View File
@@ -68,6 +68,8 @@ public:
private:
void exceptionIfInRenderPass();
Message *convert(const SDL_Event &e) const;
Message *convertJoystickEvent(const SDL_Event &e) const;
Message *convertWindowEvent(const SDL_Event &e) const;
+6 -5
View File
@@ -53,15 +53,16 @@ int w_poll(lua_State *L)
return 1;
}
int w_pump(lua_State *)
int w_pump(lua_State *L)
{
instance()->pump();
luax_catchexcept(L, [&]() { instance()->pump(); });
return 0;
}
int w_wait(lua_State *L)
{
Message *m = instance()->wait();
Message *m = nullptr;
luax_catchexcept(L, [&]() { m = instance()->wait(); });
if (m)
{
int args = m->toLua(L);
@@ -85,9 +86,9 @@ int w_push(lua_State *L)
return 1;
}
int w_clear(lua_State *)
int w_clear(lua_State *L)
{
instance()->clear();
luax_catchexcept(L, [&]() { instance()->clear(); });
return 0;
}