mirror of
https://github.com/love2d/love.git
synced 2026-08-20 04:30:09 +02:00
Fixed up the API: setCanvas (singular) now only takes one canvas, setCanvases must be used for multi-canvas rendering
--HG-- branch : MRTs
This commit is contained in:
@@ -60,11 +60,14 @@ struct FramebufferStrategy
|
|||||||
virtual void deleteFBO(GLuint, GLuint, GLuint) {}
|
virtual void deleteFBO(GLuint, GLuint, GLuint) {}
|
||||||
virtual void bindFBO(GLuint) {}
|
virtual void bindFBO(GLuint) {}
|
||||||
|
|
||||||
/// attach additional canvases to this framebuffer for rendering
|
/// attach additional canvases to the active framebuffer for rendering
|
||||||
/**
|
/**
|
||||||
* @param[in] canvases List of canvases to attach
|
* @param[in] canvases List of canvases to attach
|
||||||
**/
|
**/
|
||||||
virtual void setAttachments(const std::vector<Canvas *> &canvases) {}
|
virtual void setAttachments(const std::vector<Canvas *> &canvases) {}
|
||||||
|
|
||||||
|
/// stop using all additional attached canvases
|
||||||
|
virtual void setAttachments() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FramebufferStrategyGL3 : public FramebufferStrategy
|
struct FramebufferStrategyGL3 : public FramebufferStrategy
|
||||||
@@ -134,12 +137,17 @@ struct FramebufferStrategyGL3 : public FramebufferStrategy
|
|||||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void setAttachments()
|
||||||
|
{
|
||||||
|
// set a single render target
|
||||||
|
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||||
|
}
|
||||||
|
|
||||||
virtual void setAttachments(const std::vector<Canvas *> &canvases)
|
virtual void setAttachments(const std::vector<Canvas *> &canvases)
|
||||||
{
|
{
|
||||||
if (canvases.size() == 0)
|
if (canvases.size() == 0)
|
||||||
{
|
{
|
||||||
// set a single render target
|
setAttachments();
|
||||||
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,12 +240,17 @@ struct FramebufferStrategyPackedEXT : public FramebufferStrategy
|
|||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void setAttachments()
|
||||||
|
{
|
||||||
|
// set a single render target
|
||||||
|
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||||
|
}
|
||||||
|
|
||||||
virtual void setAttachments(const std::vector<Canvas *> &canvases)
|
virtual void setAttachments(const std::vector<Canvas *> &canvases)
|
||||||
{
|
{
|
||||||
if (canvases.size() == 0)
|
if (canvases.size() == 0)
|
||||||
{
|
{
|
||||||
// set a single render target
|
setAttachments();
|
||||||
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -431,7 +444,7 @@ void Canvas::bindDefaultCanvas()
|
|||||||
current->stopGrab();
|
current->stopGrab();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::startGrab()
|
void Canvas::setupGrab()
|
||||||
{
|
{
|
||||||
// already grabbing
|
// already grabbing
|
||||||
if (current == this)
|
if (current == this)
|
||||||
@@ -476,14 +489,18 @@ void Canvas::startGrab(const std::vector<Canvas *> &canvases)
|
|||||||
{
|
{
|
||||||
if (canvases[i]->getWidth() != width || canvases[i]->getHeight() != height)
|
if (canvases[i]->getWidth() != width || canvases[i]->getHeight() != height)
|
||||||
throw love::Exception("All canvas arguments must have the same dimensions.");
|
throw love::Exception("All canvas arguments must have the same dimensions.");
|
||||||
|
|
||||||
|
if (canvases[i]->getTextureType() != texture_type)
|
||||||
|
throw love::Exception("All canvas arguments must have the same texture type.");
|
||||||
}
|
}
|
||||||
|
|
||||||
startGrab();
|
setupGrab();
|
||||||
|
|
||||||
// don't attach anything if there's nothing to attach/detach
|
// don't attach anything if there's nothing to attach/detach
|
||||||
if (canvases.size() == 0 && attachedCanvases.size() == 0)
|
if (canvases.size() == 0 && attachedCanvases.size() == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// attach the canvas textures to this FBO and set up multiple render targets
|
||||||
strategy->setAttachments(canvases);
|
strategy->setAttachments(canvases);
|
||||||
|
|
||||||
// retain newly attached canvases
|
// retain newly attached canvases
|
||||||
@@ -497,6 +514,23 @@ void Canvas::startGrab(const std::vector<Canvas *> &canvases)
|
|||||||
attachedCanvases = canvases;
|
attachedCanvases = canvases;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Canvas::startGrab()
|
||||||
|
{
|
||||||
|
setupGrab();
|
||||||
|
|
||||||
|
if (attachedCanvases.size() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// make sure the FBO is only using a single render target
|
||||||
|
strategy->setAttachments();
|
||||||
|
|
||||||
|
// release any previously attached canvases
|
||||||
|
for (size_t i = 0; i < attachedCanvases.size(); i++)
|
||||||
|
attachedCanvases[i]->release();
|
||||||
|
|
||||||
|
attachedCanvases.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void Canvas::stopGrab()
|
void Canvas::stopGrab()
|
||||||
{
|
{
|
||||||
// i am not grabbing. leave me alone
|
// i am not grabbing. leave me alone
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ public:
|
|||||||
* to allow drawing to multiple canvases at once.
|
* to allow drawing to multiple canvases at once.
|
||||||
**/
|
**/
|
||||||
void startGrab(const std::vector<Canvas *> &canvases);
|
void startGrab(const std::vector<Canvas *> &canvases);
|
||||||
|
void startGrab();
|
||||||
void stopGrab();
|
void stopGrab();
|
||||||
|
|
||||||
void clear(const Color &c);
|
void clear(const Color &c);
|
||||||
@@ -135,7 +136,7 @@ private:
|
|||||||
|
|
||||||
std::vector<Canvas *> attachedCanvases;
|
std::vector<Canvas *> attachedCanvases;
|
||||||
|
|
||||||
void startGrab();
|
void setupGrab();
|
||||||
void drawv(const Matrix &t, const vertex *v) const;
|
void drawv(const Matrix &t, const vertex *v) const;
|
||||||
|
|
||||||
static StringMap<TextureType, TYPE_MAX_ENUM>::Entry textureTypeEntries[];
|
static StringMap<TextureType, TYPE_MAX_ENUM>::Entry textureTypeEntries[];
|
||||||
|
|||||||
@@ -47,10 +47,9 @@ int w_Canvas_renderTo(lua_State *L)
|
|||||||
if (!lua_isfunction(L, 2))
|
if (!lua_isfunction(L, 2))
|
||||||
return luaL_error(L, "Need a function to render to canvas.");
|
return luaL_error(L, "Need a function to render to canvas.");
|
||||||
|
|
||||||
static std::vector<Canvas *> attachments;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
canvas->startGrab(attachments);
|
canvas->startGrab();
|
||||||
}
|
}
|
||||||
catch (love::Exception &e)
|
catch (love::Exception &e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -942,6 +942,34 @@ int w_setCanvas(lua_State *L)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Canvas *canvas = luax_checkcanvas(L, 1);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// this unbinds the previous fbo
|
||||||
|
canvas->startGrab();
|
||||||
|
}
|
||||||
|
catch (love::Exception &e)
|
||||||
|
{
|
||||||
|
return luaL_error(L, "%s", e.what());
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int w_setCanvases(lua_State *L)
|
||||||
|
{
|
||||||
|
// discard stencil testing
|
||||||
|
instance->discardStencil();
|
||||||
|
|
||||||
|
// called with none -> reset to default buffer
|
||||||
|
// nil is an error, to help people with typoes
|
||||||
|
if (lua_isnone(L,1))
|
||||||
|
{
|
||||||
|
Canvas::bindDefaultCanvas();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool is_table = lua_istable(L, 1);
|
bool is_table = lua_istable(L, 1);
|
||||||
std::vector<Canvas *> attachments;
|
std::vector<Canvas *> attachments;
|
||||||
|
|
||||||
@@ -1474,7 +1502,7 @@ static const luaL_Reg functions[] =
|
|||||||
{ "getMaxPointSize", w_getMaxPointSize },
|
{ "getMaxPointSize", w_getMaxPointSize },
|
||||||
{ "newScreenshot", w_newScreenshot },
|
{ "newScreenshot", w_newScreenshot },
|
||||||
{ "setCanvas", w_setCanvas },
|
{ "setCanvas", w_setCanvas },
|
||||||
{ "setCanvases", w_setCanvas },
|
{ "setCanvases", w_setCanvases },
|
||||||
{ "getCanvas", w_getCanvas },
|
{ "getCanvas", w_getCanvas },
|
||||||
{ "getCanvases", w_getCanvas },
|
{ "getCanvases", w_getCanvas },
|
||||||
|
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ int w_getPointStyle(lua_State *L);
|
|||||||
int w_getMaxPointSize(lua_State *L);
|
int w_getMaxPointSize(lua_State *L);
|
||||||
int w_newScreenshot(lua_State *L);
|
int w_newScreenshot(lua_State *L);
|
||||||
int w_setCanvas(lua_State *L);
|
int w_setCanvas(lua_State *L);
|
||||||
|
int w_setCanvases(lua_State *L);
|
||||||
int w_getCanvas(lua_State *L);
|
int w_getCanvas(lua_State *L);
|
||||||
int w_setShader(lua_State *L);
|
int w_setShader(lua_State *L);
|
||||||
int w_getShader(lua_State *L);
|
int w_getShader(lua_State *L);
|
||||||
|
|||||||
Reference in New Issue
Block a user