mirror of
https://github.com/love2d/love.git
synced 2026-08-19 20:19:42 +02:00
Add guards to prevent fbo nesting
This commit is contained in:
@@ -8,6 +8,7 @@ namespace graphics
|
|||||||
namespace opengl
|
namespace opengl
|
||||||
{
|
{
|
||||||
|
|
||||||
|
bool Framebuffer::isGrabbing = false;
|
||||||
std::map<GLenum, const char*> Framebuffer::status_to_string;
|
std::map<GLenum, const char*> Framebuffer::status_to_string;
|
||||||
|
|
||||||
Framebuffer::Framebuffer(int width, int height) :
|
Framebuffer::Framebuffer(int width, int height) :
|
||||||
@@ -89,19 +90,32 @@ namespace opengl
|
|||||||
status_to_string[statusCode()];
|
status_to_string[statusCode()];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Framebuffer::grab()
|
bool Framebuffer::grab()
|
||||||
{
|
{
|
||||||
|
// don't allow nesting or forgetting Framebuffer::stop()
|
||||||
|
if (isGrabbing)
|
||||||
|
return false;
|
||||||
|
|
||||||
glPushAttrib(GL_VIEWPORT_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glPushAttrib(GL_VIEWPORT_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
glClearColor(.0f, .0f, .0f, .0f);
|
glClearColor(.0f, .0f, .0f, .0f);
|
||||||
glViewport(0, 0, width, height);
|
glViewport(0, 0, width, height);
|
||||||
|
isGrabbing = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Framebuffer::stop()
|
bool Framebuffer::stop()
|
||||||
{
|
{
|
||||||
|
if (!isGrabbing)
|
||||||
|
return false;
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
glPopAttrib();
|
glPopAttrib();
|
||||||
|
isGrabbing = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Framebuffer::draw(float x, float y, float angle, float sx, float sy, float ox, float oy) const
|
void Framebuffer::draw(float x, float y, float angle, float sx, float sy, float ox, float oy) const
|
||||||
|
|||||||
@@ -24,21 +24,23 @@ namespace opengl
|
|||||||
GLenum statusCode() const { return status_; } //SERIOUS DISLIKE HERE
|
GLenum statusCode() const { return status_; } //SERIOUS DISLIKE HERE
|
||||||
const char* statusMessage() const;
|
const char* statusMessage() const;
|
||||||
|
|
||||||
void grab();
|
bool grab();
|
||||||
void stop();
|
bool stop();
|
||||||
|
|
||||||
virtual void draw(float x, float y, float angle, float sx, float sy, float ox, float oy) const;
|
virtual void draw(float x, float y, float angle, float sx, float sy, float ox, float oy) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static bool isGrabbing;
|
||||||
|
|
||||||
GLsizei width;
|
GLsizei width;
|
||||||
GLsizei height;
|
GLsizei height;
|
||||||
GLuint fbo;
|
GLuint fbo;
|
||||||
GLuint depthbuffer;
|
GLuint depthbuffer;
|
||||||
GLuint img;
|
GLuint img;
|
||||||
GLenum status_;
|
|
||||||
|
|
||||||
vertex vertices[4];
|
vertex vertices[4];
|
||||||
|
|
||||||
|
GLenum status_;
|
||||||
static std::map<GLenum, const char*> status_to_string;
|
static std::map<GLenum, const char*> status_to_string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -17,12 +17,16 @@ namespace opengl
|
|||||||
if (!lua_isfunction(L, 2))
|
if (!lua_isfunction(L, 2))
|
||||||
return luaL_error(L, "Need a function to render to fbo");
|
return luaL_error(L, "Need a function to render to fbo");
|
||||||
|
|
||||||
fbo->grab();
|
// prevent nesting
|
||||||
|
if (!fbo->grab())
|
||||||
|
return luaL_error(L, "Cannot grab screen. May be caused by nesting or forgetting to stop()");
|
||||||
|
|
||||||
lua_settop(L, 2); // make sure the function is on top of the stack
|
lua_settop(L, 2); // make sure the function is on top of the stack
|
||||||
lua_pcall(L, 0, 0, 0);
|
lua_pcall(L, 0, 0, 0);
|
||||||
|
|
||||||
fbo->stop();
|
// fbo can be stopped in function.
|
||||||
|
if (!fbo->stop())
|
||||||
|
return luaL_error(L, "Grabbing already stopped.");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -30,14 +34,17 @@ namespace opengl
|
|||||||
int w_Framebuffer_grab(lua_State * L)
|
int w_Framebuffer_grab(lua_State * L)
|
||||||
{
|
{
|
||||||
Framebuffer * fbo = luax_checkfbo(L, 1);
|
Framebuffer * fbo = luax_checkfbo(L, 1);
|
||||||
fbo->grab();
|
// prevent nesting
|
||||||
|
if (!fbo->grab())
|
||||||
|
return luaL_error(L, "Cannot grab screen. May be caused by nesting or forgetting to stop()");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int w_Framebuffer_stop(lua_State * L)
|
int w_Framebuffer_stop(lua_State * L)
|
||||||
{
|
{
|
||||||
Framebuffer * fbo = luax_checkfbo(L, 1);
|
Framebuffer * fbo = luax_checkfbo(L, 1);
|
||||||
fbo->stop();
|
if (!fbo->stop())
|
||||||
|
return luaL_error(L, "Grabbing already stopped.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user