updated to latest love-android revision (aada9b59bcdf)

This commit is contained in:
fysx
2014-01-20 10:09:26 +01:00
parent ab51b4cc9b
commit ba5f33f9aa
45 changed files with 1112 additions and 50480 deletions
+63 -78
View File
@@ -42,14 +42,11 @@ struct FramebufferStrategy
/// create a new framebuffer and texture
/**
* @param[out] framebuffer Framebuffer name
* @param[out] img Texture name
* @param[in] width Width of framebuffer
* @param[in] height Height of framebuffer
* @param[in] texture_type Type of the canvas texture.
* @param[out] framebuffer Framebuffer name
* @param[in] texture Texture name
* @return Creation status
*/
virtual GLenum createFBO(GLuint &, GLuint &, int, int, Canvas::TextureType)
virtual GLenum createFBO(GLuint &, GLuint)
{
return GL_FRAMEBUFFER_UNSUPPORTED;
}
@@ -70,9 +67,8 @@ struct FramebufferStrategy
/**
* @param[in] framebuffer Framebuffer name
* @param[in] depth_stencil Name for packed depth and stencil buffer
* @param[in] img Texture name
*/
virtual void deleteFBO(GLuint, GLuint, GLuint) {}
virtual void deleteFBO(GLuint, GLuint) {}
virtual void bindFBO(GLuint) {}
/// attach additional canvases to the active framebuffer for rendering
@@ -87,7 +83,7 @@ struct FramebufferStrategy
struct FramebufferStrategyCore : public FramebufferStrategy
{
virtual GLenum createFBO(GLuint &framebuffer, GLuint &img, int width, int height, Canvas::TextureType texture_type)
virtual GLenum createFBO(GLuint &framebuffer, GLuint texture)
{
// get currently bound fbo to reset to it later
GLint current_fbo;
@@ -97,32 +93,8 @@ struct FramebufferStrategyCore : public FramebufferStrategy
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
// generate texture save target
GLint internalFormat;
GLenum format;
switch (texture_type)
{
case Canvas::TYPE_HDR:
internalFormat = GL_RGBA16F;
format = GL_FLOAT;
break;
case Canvas::TYPE_NORMAL:
default:
internalFormat = GL_RGBA;
format = GL_UNSIGNED_BYTE;
}
glGenTextures(1, &img);
gl.bindTexture(img);
Texture::Filter filter = Texture::getDefaultFilter();
gl.setTextureFilter(filter);
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height,
0, GL_RGBA, format, NULL);
gl.bindTexture(0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, img, 0);
GL_TEXTURE_2D, texture, 0);
// check status
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
@@ -149,9 +121,8 @@ struct FramebufferStrategyCore : public FramebufferStrategy
return glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;
}
virtual void deleteFBO(GLuint framebuffer, GLuint depth_stencil, GLuint img)
virtual void deleteFBO(GLuint framebuffer, GLuint depth_stencil)
{
gl.deleteTexture(img);
if (depth_stencil != 0)
glDeleteRenderbuffers(1, &depth_stencil);
if (framebuffer != 0)
@@ -218,7 +189,7 @@ struct FramebufferStrategyCorePacked : public FramebufferStrategyCore
struct FramebufferStrategyPackedEXT : public FramebufferStrategy
{
virtual GLenum createFBO(GLuint &framebuffer, GLuint &img, int width, int height, Canvas::TextureType texture_type)
virtual GLenum createFBO(GLuint &framebuffer, GLuint texture)
{
GLint current_fbo;
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING_EXT, &current_fbo);
@@ -227,32 +198,8 @@ struct FramebufferStrategyPackedEXT : public FramebufferStrategy
glGenFramebuffersEXT(1, &framebuffer);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer);
// generate texture save target
GLint internalFormat;
GLenum format;
switch (texture_type)
{
case Canvas::TYPE_HDR:
internalFormat = GL_RGBA16F;
format = GL_FLOAT;
break;
case Canvas::TYPE_NORMAL:
default:
internalFormat = GL_RGBA;
format = GL_UNSIGNED_BYTE;
}
glGenTextures(1, &img);
gl.bindTexture(img);
Texture::Filter filter = Texture::getDefaultFilter();
gl.setTextureFilter(filter);
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height,
0, GL_RGBA, format, NULL);
gl.bindTexture(0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D, img, 0);
GL_TEXTURE_2D, texture, 0);
// check status
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
@@ -279,9 +226,8 @@ struct FramebufferStrategyPackedEXT : public FramebufferStrategy
return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT;
}
virtual void deleteFBO(GLuint framebuffer, GLuint depth_stencil, GLuint img)
virtual void deleteFBO(GLuint framebuffer, GLuint depth_stencil)
{
gl.deleteTexture(img);
if (depth_stencil != 0)
glDeleteRenderbuffersEXT(1, &depth_stencil);
if (framebuffer != 0)
@@ -347,9 +293,9 @@ struct FramebufferStrategyEXT : public FramebufferStrategyPackedEXT
bool isSupported()
{
GLuint fb = 0, stencil = 0, img = 0;
GLenum status = createFBO(fb, img, 2, 2, Canvas::TYPE_NORMAL);
deleteFBO(fb, stencil, img);
GLuint fb = 0, stencil = 0;
GLenum status = createFBO(fb, 0);
deleteFBO(fb, stencil);
return status == GL_FRAMEBUFFER_COMPLETE;
}
};
@@ -391,8 +337,8 @@ static int maxDrawBuffers = 0;
Canvas::Canvas(int width, int height, TextureType texture_type)
: fbo(0)
, texture(0)
, depth_stencil(0)
, img(0)
, texture_type(texture_type)
{
this->width = width;
@@ -437,7 +383,7 @@ Canvas::~Canvas()
bool Canvas::loadVolatile()
{
fbo = depth_stencil = img = 0;
fbo = depth_stencil = texture = 0;
// glTexImage2D is guaranteed to error in this case.
if (width > gl.getMaxTextureSize() || height > gl.getMaxTextureSize())
@@ -446,20 +392,59 @@ bool Canvas::loadVolatile()
return false;
}
status = strategy->createFBO(fbo, img, width, height, texture_type);
if (status != GL_FRAMEBUFFER_COMPLETE)
return false;
glGenTextures(1, &texture);
gl.bindTexture(texture);
setFilter(filter);
setWrap(wrap);
GLint internalformat;
GLenum textype;
switch (texture_type)
{
case TYPE_HDR:
internalformat = GL_RGBA16F;
textype = GL_FLOAT;
break;
case TYPE_NORMAL:
default:
internalformat = GL_RGBA8;
textype = GL_UNSIGNED_BYTE;
}
while (glGetError() != GL_NO_ERROR)
/* Clear the error buffer. */;
glTexImage2D(GL_TEXTURE_2D,
0,
internalformat,
width, height,
0,
GL_RGBA,
textype,
nullptr);
if (glGetError() != GL_NO_ERROR)
{
status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
return false;
}
status = strategy->createFBO(fbo, texture);
if (status != GL_FRAMEBUFFER_COMPLETE)
return false;
clear(Color(0, 0, 0, 0));
return true;
}
void Canvas::unloadVolatile()
{
strategy->deleteFBO(fbo, depth_stencil, img);
fbo = depth_stencil = img = 0;
strategy->deleteFBO(fbo, depth_stencil);
gl.deleteTexture(texture);
fbo = depth_stencil = texture = 0;
for (size_t i = 0; i < attachedCanvases.size(); i++)
attachedCanvases[i]->release();
@@ -513,25 +498,25 @@ void Canvas::drawq(Quad *quad, float x, float y, float angle, float sx, float sy
void Canvas::setFilter(const Texture::Filter &f)
{
filter = f;
gl.bindTexture(img);
gl.bindTexture(texture);
gl.setTextureFilter(filter);
}
void Canvas::setWrap(const Texture::Wrap &w)
{
wrap = w;
gl.bindTexture(img);
gl.bindTexture(texture);
gl.setTextureWrap(wrap);
}
GLuint Canvas::getGLTexture() const
{
return img;
return texture;
}
void Canvas::predraw() const
{
gl.bindTexture(img);
gl.bindTexture(texture);
}
void Canvas::setupGrab()
@@ -113,8 +113,8 @@ public:
private:
GLuint fbo;
GLuint texture;
GLuint depth_stencil;
GLuint img;
TextureType texture_type;
+35 -4
View File
@@ -46,6 +46,7 @@ Font::Font(love::font::Rasterizer *r, const Texture::Filter &filter)
, lineHeight(1)
, mSpacing(1)
, filter(filter)
, useSpacesAsTab(false)
{
this->filter.mipmap = Texture::FILTER_NONE;
@@ -67,13 +68,16 @@ Font::Font(love::font::Rasterizer *r, const Texture::Filter &filter)
textureWidth = TEXTURE_WIDTHS[textureSizeIndex];
textureHeight = TEXTURE_HEIGHTS[textureSizeIndex];
love::font::GlyphData *gd = 0;
love::font::GlyphData *gd = nullptr;
try
{
gd = r->getGlyphData(32);
gd = r->getGlyphData(32); // Space character.
type = (gd->getFormat() == love::font::GlyphData::FORMAT_LUMINANCE_ALPHA) ? FONT_TRUETYPE : FONT_IMAGE;
if (!r->hasGlyph(9)) // No tab character in the Rasterizer.
useSpacesAsTab = true;
loadVolatile();
}
catch (love::Exception &)
@@ -172,7 +176,26 @@ void Font::createTexture()
Font::Glyph *Font::addGlyph(uint32 glyph)
{
love::font::GlyphData *gd = rasterizer->getGlyphData(glyph);
love::font::GlyphData *gd = nullptr;
// Use spaces for the tab 'glyph'.
if (glyph == 9 && useSpacesAsTab)
{
love::font::GlyphData *spacegd = rasterizer->getGlyphData(32);
love::font::GlyphMetrics gm = {};
gm.advance = spacegd->getAdvance() * SPACES_PER_TAB;
gm.bearingX = spacegd->getBearingX();
gm.bearingY = spacegd->getBearingY();
love::font::GlyphData::Format f = spacegd->getFormat();
spacegd->release();
gd = new love::font::GlyphData(glyph, gm, f);
}
else
gd = rasterizer->getGlyphData(glyph);
int w = gd->getWidth();
int h = gd->getHeight();
@@ -186,7 +209,15 @@ Font::Glyph *Font::addGlyph(uint32 glyph)
if (textureY + h + TEXTURE_PADDING > textureHeight)
{
// totally out of space - new texture!
createTexture();
try
{
createTexture();
}
catch (love::Exception &)
{
gd->release();
throw;
}
}
Glyph *g = new Glyph;
+7 -2
View File
@@ -202,14 +202,19 @@ private:
FontType type;
Texture::Filter filter;
int textureX, textureY;
int rowHeight;
bool useSpacesAsTab;
static const int NUM_TEXTURE_SIZES = 7;
static const int TEXTURE_WIDTHS[NUM_TEXTURE_SIZES];
static const int TEXTURE_HEIGHTS[NUM_TEXTURE_SIZES];
static const int TEXTURE_PADDING = 1;
int textureX, textureY;
int rowHeight;
// This will be used if the Rasterizer doesn't have a tab character itself.
static const int SPACES_PER_TAB = 4;
}; // Font
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -119,6 +119,7 @@ ParticleSystem::ParticleSystem(const ParticleSystem &p)
, emissionRate(p.emissionRate)
, emitCounter(0.0f)
, position(p.position)
, prevPosition(p.prevPosition)
, areaSpreadDistribution(p.areaSpreadDistribution)
, areaSpread(p.areaSpread)
, lifetime(p.lifetime)
@@ -215,14 +216,14 @@ uint32 ParticleSystem::getBufferSize() const
return maxParticles;
}
void ParticleSystem::addParticle()
void ParticleSystem::addParticle(float t)
{
if (isFull())
return;
// Gets a free particle and updates the allocation pointer.
particle *p = pFree++;
initParticle(p);
initParticle(p, t);
switch (insertMode)
{
@@ -241,10 +242,13 @@ void ParticleSystem::addParticle()
activeParticles++;
}
void ParticleSystem::initParticle(particle *p)
void ParticleSystem::initParticle(particle *p, float t)
{
float min,max;
// Linearly interpolate between the previous and current emitter position.
love::Vector pos = prevPosition + (position - prevPosition) * t;
min = particleLifeMin;
max = particleLifeMax;
if (min == max)
@@ -253,8 +257,8 @@ void ParticleSystem::initParticle(particle *p)
p->life = (float) rng.random(min, max);
p->lifetime = p->life;
p->position[0] = position.getX();
p->position[1] = position.getY();
p->position[0] = pos.x;
p->position[1] = pos.y;
switch (areaSpreadDistribution)
{
@@ -275,7 +279,7 @@ void ParticleSystem::initParticle(particle *p)
max = direction + spread/2.0f;
p->direction = (float) rng.random(min, max);
p->origin = position;
p->origin = pos;
min = speedMin;
max = speedMax;
@@ -758,7 +762,7 @@ void ParticleSystem::emit(uint32 num)
num = std::min(num, maxParticles - activeParticles);
while(num--)
addParticle();
addParticle(1.0f);
}
bool ParticleSystem::isActive() const
@@ -860,25 +864,6 @@ void ParticleSystem::update(float dt)
if (pMem == nullptr || dt == 0.0f)
return;
// Make some more particles.
if (active)
{
float rate = 1.0f / emissionRate; // the amount of time between each particle emit
emitCounter += dt;
while (emitCounter > rate)
{
addParticle();
emitCounter -= rate;
}
/*int particles = (int)(emissionRate * dt);
for (int i = 0; i != particles; i++)
add();*/
life -= dt;
if (lifetime != -1 && life < 0)
stop();
}
// Traverse all particles and update.
particle *p = pHead;
@@ -953,6 +938,28 @@ void ParticleSystem::update(float dt)
p = p->next;
}
}
// Make some more particles.
if (active)
{
float rate = 1.0f / emissionRate; // the amount of time between each particle emit
emitCounter += dt;
float total = emitCounter - rate;
while (emitCounter > rate)
{
addParticle(1.0f - (emitCounter - rate) / total);
emitCounter -= rate;
}
/*int particles = (int)(emissionRate * dt);
for (int i = 0; i != particles; i++)
add();*/
life -= dt;
if (lifetime != -1 && life < 0)
stop();
}
prevPosition = position;
}
bool ParticleSystem::getConstant(const char *in, AreaSpreadDistribution &out)
@@ -558,6 +558,7 @@ protected:
// The relative position of the particle emitter.
love::Vector position;
love::Vector prevPosition;
// Emission area spread.
AreaSpreadDistribution areaSpreadDistribution;
@@ -614,11 +615,11 @@ protected:
void createBuffers(size_t size);
void deleteBuffers();
void addParticle();
void addParticle(float t);
particle *removeParticle(particle *p);
// Called by addParticle.
void initParticle(particle *p);
void initParticle(particle *p, float t);
void insertTop(particle *p);
void insertBottom(particle *p);
void insertRandom(particle *p);
@@ -127,6 +127,11 @@ VBO::VBO(size_t size, GLenum target, GLenum usage, MemoryBacking backing)
if (!(GLAD_ARB_vertex_buffer_object || GLAD_VERSION_1_5 || GLAD_ES_VERSION_2_0))
throw love::Exception("Not supported");
// FIXME:
// ES2 can't do glGetBufferSubData.
if (GLAD_ES_VERSION_2_0)
backing = BACKING_FULL;
if (getMemoryBacking() == BACKING_FULL)
memory_map = malloc(getSize());
@@ -34,22 +34,21 @@ Canvas *luax_checkcanvas(lua_State *L, int idx)
int w_Canvas_renderTo(lua_State *L)
{
// As startGrab() clears the framebuffer, better not allow
// grabbing inside another grabbing
if (Canvas::current != NULL)
{
Canvas::bindDefaultCanvas();
return luaL_error(L, "Current render target not the default canvas!");
}
Canvas *canvas = luax_checkcanvas(L, 1);
luaL_checktype(L, 2, LUA_TFUNCTION);
// Save the current Canvas so we can restore it when we're done.
Canvas *oldcanvas = Canvas::current;
EXCEPT_GUARD(canvas->startGrab();)
lua_settop(L, 2); // make sure the function is on top of the stack
lua_call(L, 0, 0);
canvas->stopGrab();
if (oldcanvas != nullptr)
oldcanvas->startGrab(oldcanvas->getAttachedCanvases());
else
Canvas::bindDefaultCanvas();
return 0;
}
@@ -1152,8 +1152,9 @@ int w_line(lua_State *L)
args = lua_objlen(L, 1);
is_table = true;
}
if (args % 2 != 0)
return luaL_error(L, "Number of vertices must be a multiple of two");
return luaL_error(L, "Number of vertex components must be a multiple of two");
else if (args < 4)
return luaL_error(L, "Need at least two vertices to draw a line");
@@ -1254,7 +1255,7 @@ int w_polygon(lua_State *L)
}
if (args % 2 != 0)
return luaL_error(L, "Number of vertices must be a multiple of two");
return luaL_error(L, "Number of vertex components must be a multiple of two");
else if (args < 6)
return luaL_error(L, "Need at least three vertices to draw a polygon");