Added first review of vrld's FBO patch

This commit is contained in:
Bart van Strien
2010-08-10 19:05:56 +02:00
parent afa865973d
commit f87738edb5
9 changed files with 292 additions and 31 deletions
+2
View File
@@ -52,6 +52,7 @@ namespace love
GRAPHICS_PARTICLE_SYSTEM_ID, GRAPHICS_PARTICLE_SYSTEM_ID,
GRAPHICS_SPRITE_BATCH_ID, GRAPHICS_SPRITE_BATCH_ID,
GRAPHICS_VERTEX_BUFFER_ID, GRAPHICS_VERTEX_BUFFER_ID,
GRAPHICS_FBO_ID,
// Image // Image
IMAGE_IMAGE_DATA_ID, IMAGE_IMAGE_DATA_ID,
@@ -116,6 +117,7 @@ namespace love
const bits GRAPHICS_PARTICLE_SYSTEM_T = (bits(1) << GRAPHICS_PARTICLE_SYSTEM_ID) | GRAPHICS_DRAWABLE_T; const bits GRAPHICS_PARTICLE_SYSTEM_T = (bits(1) << GRAPHICS_PARTICLE_SYSTEM_ID) | GRAPHICS_DRAWABLE_T;
const bits GRAPHICS_SPRITE_BATCH_T = (bits(1) << GRAPHICS_SPRITE_BATCH_ID) | GRAPHICS_DRAWABLE_T; const bits GRAPHICS_SPRITE_BATCH_T = (bits(1) << GRAPHICS_SPRITE_BATCH_ID) | GRAPHICS_DRAWABLE_T;
const bits GRAPHICS_VERTEX_BUFFER_T = (bits(1) << GRAPHICS_VERTEX_BUFFER_ID) | GRAPHICS_DRAWABLE_T; const bits GRAPHICS_VERTEX_BUFFER_T = (bits(1) << GRAPHICS_VERTEX_BUFFER_ID) | GRAPHICS_DRAWABLE_T;
const bits GRAPHICS_FBO_T = (bits(1) << GRAPHICS_FBO_ID) | GRAPHICS_DRAWABLE_T;
// Image. // Image.
const bits IMAGE_IMAGE_DATA_T = (bits(1) << IMAGE_IMAGE_DATA_ID) | DATA_T; const bits IMAGE_IMAGE_DATA_T = (bits(1) << IMAGE_IMAGE_DATA_ID) | DATA_T;
+103
View File
@@ -0,0 +1,103 @@
#include "Fbo.h"
#include <common/Matrix.h>
namespace love
{
namespace graphics
{
namespace opengl
{
Fbo::Fbo(int width, int height) :
width(width), height(height)
{
// world coordinates
vertices[0].x = 0; vertices[0].y = 0;
vertices[1].x = 0; vertices[1].y = height;
vertices[2].x = width; vertices[2].y = height;
vertices[3].x = width; vertices[3].y = 0;
// texture coordinates
vertices[0].s = 0; vertices[0].t = 1;
vertices[1].s = 0; vertices[1].t = 0;
vertices[2].s = 1; vertices[2].t = 0;
vertices[3].s = 1; vertices[3].t = 1;
// generate depth buffer
glGenRenderbuffers(1, &depthbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
// generate texture save target
glGenTextures(1, &img);
glBindTexture(GL_TEXTURE_2D, img);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height,
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_2D, 0);
// create framebuffer
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, img, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, depthbuffer);
status_ = glCheckFramebufferStatus(GL_FRAMEBUFFER);
// unbind buffers and texture
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
Fbo::~Fbo()
{
glDeleteTextures(1, &fbo);
glDeleteRenderbuffers(1, &depthbuffer);
glDeleteFramebuffers(1, &img);
}
GLenum Fbo::status() const
{
return status_;
}
void Fbo::bind()
{
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);
glViewport(0, 0, width, height);
}
void Fbo::unbind()
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glPopAttrib();
}
void Fbo::draw(float x, float y, float angle, float sx, float sy, float ox, float oy) const
{
static Matrix t;
t.setTransformation(x, y, angle, sx, sy, ox, oy);
glPushMatrix();
glMultMatrixf((const GLfloat*)t.getElements());
glBindTexture(GL_TEXTURE_2D, img);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid*)&vertices[0].x);
glTexCoordPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid*)&vertices[0].s);
glDrawArrays(GL_QUADS, 0, 4);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glPopMatrix();
}
} // opengl
} // graphics
} // love
+46
View File
@@ -0,0 +1,46 @@
#ifndef LOVE_GRAPHICS_FBO_H
#define LOVE_GRAPHICS_FBO_H
#include <graphics/Drawable.h>
#include <graphics/Volatile.h>
#include <common/math.h>
#include "GLee.h"
namespace love
{
namespace graphics
{
namespace opengl
{
class Fbo : public Drawable // Fbo vs. FBO?
{
public:
Fbo(int width, int height);
virtual ~Fbo();
GLenum status() const; //SERIOUS DISLIKE HERE
void bind(); //DOUBTFUL ABOUT NAME
void unbind(); //Maybe start/stop?
//And what about clearing, clear() isn't entirely what I want either
//maybe make bind/start autoclear?
virtual void draw(float x, float y, float angle, float sx, float sy, float ox, float oy) const;
private:
GLsizei width;
GLsizei height;
GLuint fbo;
GLuint depthbuffer;
GLuint img;
GLenum status_;
vertex vertices[4];
};
} // opengl
} // graphics
} // love
#endif // LOVE_GRAPHICS_FBO_H
+5
View File
@@ -470,6 +470,11 @@ namespace opengl
return new ParticleSystem(image, size); return new ParticleSystem(image, size);
} }
Fbo * Graphics::newFbo(int width, int height)
{
return new Fbo(width, height);
}
void Graphics::setColor(Color c) void Graphics::setColor(Color c)
{ {
glColor4ubv(&c.r); glColor4ubv(&c.r);
+3
View File
@@ -43,6 +43,7 @@
#include "Quad.h" #include "Quad.h"
#include "SpriteBatch.h" #include "SpriteBatch.h"
#include "ParticleSystem.h" #include "ParticleSystem.h"
#include "Fbo.h"
namespace love namespace love
{ {
@@ -260,6 +261,8 @@ namespace opengl
ParticleSystem * newParticleSystem(Image * image, int size); ParticleSystem * newParticleSystem(Image * image, int size);
Fbo * newFbo(int width, int height);
/** /**
* Sets the foreground color. * Sets the foreground color.
**/ **/
+58
View File
@@ -0,0 +1,58 @@
#include "wrap_Fbo.h"
namespace love
{
namespace graphics
{
namespace opengl
{
Fbo * luax_checkfbo(lua_State * L, int idx)
{
return luax_checktype<Fbo>(L, idx, "Fbo", GRAPHICS_FBO_T);
}
int w_Fbo_render(lua_State * L)
{
Fbo * fbo = luax_checkfbo(L, 1);
if (!lua_isfunction(L, 2))
return luaL_error(L, "Need a function to render to fbo");
fbo->bind();
lua_settop(L, 2); // make sure the function is on top of the stack
lua_pcall(L, 0, 0, 0);
fbo->unbind();
return 0;
}
int w_Fbo_bind(lua_State * L)
{
Fbo * fbo = luax_checkfbo(L, 1);
fbo->bind();
return 0;
}
int w_Fbo_unbind(lua_State * L)
{
Fbo * fbo = luax_checkfbo(L, 1);
fbo->unbind();
return 0;
}
static const luaL_Reg functions[] = {
{ "render", w_Fbo_render },
{ "bind", w_Fbo_bind },
{ "unbind", w_Fbo_unbind },
{ 0, 0 }
};
int luaopen_fbo(lua_State * L)
{
return luax_register_type(L, "Fbo", functions);
}
} // opengl
} // graphics
} // love
+25
View File
@@ -0,0 +1,25 @@
#ifndef LOVE_GRAPHICS_OPENGL_WRAP_FBO_H
#define LOVE_GRAPHICS_OPENGL_WRAP_FBO_H
// LOVE
#include <common/runtime.h>
#include "Fbo.h"
namespace love
{
namespace graphics
{
namespace opengl
{
//see Fbo.h
Fbo * luax_checkfbo(lua_State * L, int idx);
int w_Fbo_render(lua_State * L);
int w_Fbo_bind(lua_State * L);
int w_Fbo_unbind(lua_State * L);
int luaopen_fbo(lua_State * L);
} // opengl
} // graphics
} // love
#endif // LOVE_GRAPHICS_OPENGL_WRAP_FBO_H
@@ -292,6 +292,21 @@ namespace opengl
return 1; return 1;
} }
int w_newFbo(lua_State * L)
{
int width, height;
width = luaL_checkint(L, 1);
height = luaL_checkint(L, 2);
Fbo * fbo = instance->newFbo(width, height);
//and there we go with the status... still disliked
GLenum status = fbo->status();
if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
return luaL_error(L, "Cannot create FBO: %d", status);
luax_newtype(L, "Fbo", GRAPHICS_FBO_T, (void*)fbo);
return 1;
}
int w_setColor(lua_State * L) int w_setColor(lua_State * L)
{ {
Color c; Color c;
@@ -829,6 +844,7 @@ namespace opengl
{ "newImageFont", w_newImageFont }, { "newImageFont", w_newImageFont },
{ "newSpriteBatch", w_newSpriteBatch }, { "newSpriteBatch", w_newSpriteBatch },
{ "newParticleSystem", w_newParticleSystem }, { "newParticleSystem", w_newParticleSystem },
{ "newFbo", w_newFbo },
{ "setColor", w_setColor }, { "setColor", w_setColor },
{ "getColor", w_getColor }, { "getColor", w_getColor },
@@ -906,6 +922,7 @@ namespace opengl
luaopen_frame, luaopen_frame,
luaopen_spritebatch, luaopen_spritebatch,
luaopen_particlesystem, luaopen_particlesystem,
luaopen_fbo,
0 0
}; };
@@ -28,6 +28,7 @@
#include "wrap_Quad.h" #include "wrap_Quad.h"
#include "wrap_SpriteBatch.h" #include "wrap_SpriteBatch.h"
#include "wrap_ParticleSystem.h" #include "wrap_ParticleSystem.h"
#include "wrap_Fbo.h"
#include "Graphics.h" #include "Graphics.h"
namespace love namespace love
@@ -58,6 +59,7 @@ namespace opengl
int w_newImageFont(lua_State * L); int w_newImageFont(lua_State * L);
int w_newSpriteBatch(lua_State * L); int w_newSpriteBatch(lua_State * L);
int w_newParticleSystem(lua_State * L); int w_newParticleSystem(lua_State * L);
int w_newFbo(lua_State * L); // commetns in function
int w_setColor(lua_State * L); int w_setColor(lua_State * L);
int w_getColor(lua_State * L); int w_getColor(lua_State * L);
int w_setBackgroundColor(lua_State * L); int w_setBackgroundColor(lua_State * L);