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:
vrld
2010-08-26 20:44:30 +02:00
parent 98feae1950
commit 320ac05fd1
6 changed files with 67 additions and 56 deletions
+30 -14
View File
@@ -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
+8 -6
View File
@@ -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);