mirror of
https://github.com/love2d/love.git
synced 2026-08-12 08:30:56 +02:00
Move fbo:grab() to love.graphics.setRenderTarget( fbo ) Move fbo:stop() to love.graphics.setRenderTarget( nil ) Rename fbo:render( func ) to fbo:renderTo( func )
This commit is contained in:
@@ -7,8 +7,8 @@ namespace graphics
|
||||
{
|
||||
namespace opengl
|
||||
{
|
||||
Framebuffer* Framebuffer::current = NULL;
|
||||
|
||||
bool Framebuffer::isGrabbing = false;
|
||||
Framebuffer::Framebuffer(int width, int height) :
|
||||
width(width), height(height)
|
||||
{
|
||||
@@ -47,7 +47,7 @@ namespace opengl
|
||||
GL_TEXTURE_2D, img, 0);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
|
||||
GL_RENDERBUFFER, depthbuffer);
|
||||
status_ = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
|
||||
// unbind buffers and texture
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
@@ -55,37 +55,53 @@ namespace opengl
|
||||
|
||||
Framebuffer::~Framebuffer()
|
||||
{
|
||||
// reset framebuffer if still using this one
|
||||
if (current == this)
|
||||
stopGrab();
|
||||
|
||||
// clear fbo
|
||||
glDeleteTextures(1, &fbo);
|
||||
glDeleteRenderbuffers(1, &depthbuffer);
|
||||
glDeleteFramebuffers(1, &img);
|
||||
}
|
||||
|
||||
bool Framebuffer::grab()
|
||||
void Framebuffer::bindDefaultBuffer()
|
||||
{
|
||||
// don't allow nesting or forgetting Framebuffer::stop()
|
||||
if (isGrabbing)
|
||||
return false;
|
||||
if (current != NULL)
|
||||
current->stopGrab();
|
||||
}
|
||||
|
||||
void Framebuffer::startGrab()
|
||||
{
|
||||
// already grabbing
|
||||
if (current == this)
|
||||
return;
|
||||
|
||||
// cleanup after previous fbo
|
||||
if (current != NULL)
|
||||
glPopAttrib();
|
||||
|
||||
// bind buffer and clear screen
|
||||
glPushAttrib(GL_VIEWPORT_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glClearColor(.0f, .0f, .0f, .0f);
|
||||
glViewport(0, 0, width, height);
|
||||
isGrabbing = true;
|
||||
|
||||
return true;
|
||||
// indicate
|
||||
current = this;
|
||||
}
|
||||
|
||||
bool Framebuffer::stop()
|
||||
void Framebuffer::stopGrab()
|
||||
{
|
||||
if (!isGrabbing)
|
||||
return false;
|
||||
// i am not grabbing. leave me alone
|
||||
if (current != this)
|
||||
return;
|
||||
|
||||
// bind default
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glPopAttrib();
|
||||
isGrabbing = false;
|
||||
|
||||
return true;
|
||||
current = NULL;
|
||||
}
|
||||
|
||||
void Framebuffer::draw(float x, float y, float angle, float sx, float sy, float ox, float oy) const
|
||||
|
||||
@@ -20,16 +20,18 @@ namespace opengl
|
||||
Framebuffer(int width, int height);
|
||||
virtual ~Framebuffer();
|
||||
|
||||
unsigned int getStatus() const { return status_; }
|
||||
unsigned int getStatus() const { return status; }
|
||||
|
||||
bool grab();
|
||||
bool stop();
|
||||
static Framebuffer* current;
|
||||
static void bindDefaultBuffer();
|
||||
|
||||
void startGrab();
|
||||
void stopGrab();
|
||||
|
||||
virtual void draw(float x, float y, float angle, float sx, float sy, float ox, float oy) const;
|
||||
|
||||
private:
|
||||
static bool isGrabbing;
|
||||
|
||||
private:
|
||||
GLsizei width;
|
||||
GLsizei height;
|
||||
GLuint fbo;
|
||||
@@ -38,7 +40,7 @@ namespace opengl
|
||||
|
||||
vertex vertices[4];
|
||||
|
||||
GLenum status_;
|
||||
GLenum status;
|
||||
};
|
||||
|
||||
} // opengl
|
||||
|
||||
@@ -11,51 +11,29 @@ namespace opengl
|
||||
return luax_checktype<Framebuffer>(L, idx, "Framebuffer", GRAPHICS_FRAMEBUFFER_T);
|
||||
}
|
||||
|
||||
int w_Framebuffer_render(lua_State * L)
|
||||
int w_Framebuffer_renderTo(lua_State * L)
|
||||
{
|
||||
// As startGrab() clears the framebuffer, better not allow
|
||||
// grabbing inside another grabbing
|
||||
if (Framebuffer::current != NULL) {
|
||||
Framebuffer::bindDefaultBuffer();
|
||||
return luaL_error(L, "Current render target not the default framebuffer!");
|
||||
}
|
||||
|
||||
Framebuffer * fbo = luax_checkfbo(L, 1);
|
||||
if (!lua_isfunction(L, 2))
|
||||
return luaL_error(L, "Need a function to render to fbo");
|
||||
|
||||
// prevent nesting
|
||||
if (!fbo->grab()) {
|
||||
fbo->stop(); // stop grabbing so errormessage is shown
|
||||
return luaL_error(L, "Framebuffer:grab(): Cannot grab screen. Be sure to match every Framebuffer:grab() with Framebuffer:stop().");
|
||||
}
|
||||
|
||||
fbo->startGrab();
|
||||
lua_settop(L, 2); // make sure the function is on top of the stack
|
||||
lua_call(L, 0, 0);
|
||||
fbo->stopGrab();
|
||||
|
||||
// fbo can be stopped in function.
|
||||
if (!fbo->stop())
|
||||
return luaL_error(L, "Framebuffer:render(): Screengrabbing already stopped.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_Framebuffer_grab(lua_State * L)
|
||||
{
|
||||
Framebuffer * fbo = luax_checkfbo(L, 1);
|
||||
// prevent nesting
|
||||
if (!fbo->grab()) {
|
||||
fbo->stop(); // stop grabbing so errormessage is shown
|
||||
return luaL_error(L, "Framebuffer:grab(): Cannot grab screen. Be sure to match every Framebuffer:grab() with Framebuffer:stop().");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_Framebuffer_stop(lua_State * L)
|
||||
{
|
||||
Framebuffer * fbo = luax_checkfbo(L, 1);
|
||||
if (!fbo->stop())
|
||||
return luaL_error(L, "Framebuffer:stop(): Screengrabbing already stopped.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const luaL_Reg functions[] = {
|
||||
{ "render", w_Framebuffer_render },
|
||||
{ "grab", w_Framebuffer_grab },
|
||||
{ "stop", w_Framebuffer_stop },
|
||||
{ "renderTo", w_Framebuffer_renderTo },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
@@ -13,9 +13,7 @@ namespace opengl
|
||||
{
|
||||
//see Framebuffer.h
|
||||
Framebuffer * luax_checkfbo(lua_State * L, int idx);
|
||||
int w_Framebuffer_render(lua_State * L);
|
||||
int w_Framebuffer_bind(lua_State * L);
|
||||
int w_Framebuffer_unbind(lua_State * L);
|
||||
int w_Framebuffer_renderTo(lua_State * L);
|
||||
int luaopen_framebuffer(lua_State * L);
|
||||
|
||||
} // opengl
|
||||
|
||||
@@ -595,6 +595,21 @@ namespace opengl
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_setRenderTarget(lua_State * L)
|
||||
{
|
||||
// called with nil -> reset to default buffer
|
||||
if (lua_isnil(L, 1)) {
|
||||
Framebuffer::bindDefaultBuffer();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Framebuffer * fbo = luax_checkfbo(L, 1);
|
||||
// this unbinds the previous fbo
|
||||
fbo->startGrab();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws an Image at the specified coordinates, with rotation and
|
||||
* scaling along both axes.
|
||||
@@ -885,6 +900,7 @@ namespace opengl
|
||||
{ "getPointStyle", w_getPointStyle },
|
||||
{ "getMaxPointSize", w_getMaxPointSize },
|
||||
{ "newScreenshot", w_newScreenshot },
|
||||
{ "setRenderTarget", w_setRenderTarget },
|
||||
|
||||
{ "draw", w_draw },
|
||||
{ "drawq", w_drawq },
|
||||
|
||||
@@ -84,6 +84,7 @@ namespace opengl
|
||||
int w_getPointStyle(lua_State * L);
|
||||
int w_getMaxPointSize(lua_State * L);
|
||||
int w_newScreenshot(lua_State * L);
|
||||
int w_setRenderTarget(lua_State * L);
|
||||
int w_draw(lua_State * L);
|
||||
int w_drawq(lua_State * L);
|
||||
int w_drawTest(lua_State * L);
|
||||
|
||||
Reference in New Issue
Block a user