Add Geometries (replaces Quads).

A Geometry is a collection of vertices describing a non self-intersecting
(simple) polygon. In addition to screen coordinates, the vertices have
attributes for texture coordinates (s,t) and color (r,g,b,a).

It can be used as a quad, to display distorted images, or anything in between.

Added:
^^^^^^

-- geometry from table, where table has the format:
-- info = {
-- {x,y, s,t, [r = 255, g = 255, b = 255, a = 255]}
-- {x,y, s,t, [r = 255, g = 255, b = 255, a = 255]}
-- ...
-- }
geom = love.graphics.newGeometry(info)

-- convenience wrapper for quads (same as before)
geom = love.graphics.newQuad(x,y, w,h, sw,sh)

-- retrieve vertex i (1-indexed)
x,y,s,t,r,g,b,a = geom:getVertex(i)

-- set vertex i (1-indexed)
geom:setVertex(i, x,y, s,t, [r,g,b,a])

-- flip geometry
geom:flip(x, y)


Renamed:
^^^^^^^^

love.graphics.drawq() -> love.graphics.drawg()


Removed:
^^^^^^^^

quad:setViewport()
quad:getViewport()
This commit is contained in:
vrld
2013-04-21 18:53:13 +02:00
parent 9d62d0044c
commit 71317c4359
28 changed files with 750 additions and 229 deletions
+33
View File
@@ -0,0 +1,33 @@
/**
* Copyright (c) 2006-2013 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "DrawGable.h"
namespace love
{
namespace graphics
{
DrawGable::~DrawGable()
{
}
} // graphics
} // love
+65
View File
@@ -0,0 +1,65 @@
/**
* Copyright (c) 2006-2013 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_GRAPHICS_DRAWGABLE_H
#define LOVE_GRAPHICS_DRAWGABLE_H
// LOVE
#include "Drawable.h"
#include "Geometry.h"
namespace love
{
namespace graphics
{
/**
* A DrawGable is anything that be drawn in part with a Geometry object.
**/
class DrawGable : public Drawable
{
public:
/**
* Destructor.
**/
virtual ~DrawGable();
/**
* Draws the object with the specified transformation.
*
* @param geom The Geometry object to use to draw the object.
* @param x The position of the object along the x-axis.
* @param y The position of the object along the y-axis.
* @param angle The angle of the object (in radians).
* @param sx The scale factor along the x-axis.
* @param sy The scale factor along the y-axis.
* @param ox The origin offset along the x-axis.
* @param oy The origin offset along the y-axis.
* @param kx Shear along the x-axis.
* @param ky Shear along the y-axis.
**/
virtual void drawg(Geometry *geom, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const = 0;
};
} // graphics
} // love
#endif // LOVE_GRAPHICS_DRAWGABLE_H
+164
View File
@@ -0,0 +1,164 @@
/**
* Copyright (c) 2006-2012 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "Geometry.h"
#include "common/Exception.h"
#include "modules/math/MathModule.h"
using love::math::Math;
// STD
#include <limits>
#include <algorithm> // for std::swap()
#include <cstring> // For memcpy
namespace love
{
namespace graphics
{
Geometry::Geometry(const std::vector<vertex> &p)
: polygon(p)
, vertexArray(NULL)
, x_min(std::numeric_limits<float>::max())
, x_max(std::numeric_limits<float>::min())
, y_min(std::numeric_limits<float>::max())
, y_max(std::numeric_limits<float>::min())
{
for (size_t i = 0; i < polygon.size(); ++i)
{
const vertex &v = polygon[i];
x_min = v.x < x_min ? v.x : x_min;
x_max = v.x > x_max ? v.x : x_max;
y_min = v.y < y_min ? v.y : y_min;
y_max = v.y > y_max ? v.y : y_max;
}
triangulate();
}
Geometry::Geometry(float x, float y, float w, float h, float sw, float sh)
: vertexArray(NULL)
, x_min(x)
, x_max(x+w)
, y_min(y)
, y_max(y+h)
{
float s0 = x/sw, s1 = (x+w)/sw, t0 = y/sh, t1 = (y+h)/sh;
polygon.resize(4);
polygon[0] = vertex(0,0, s0,t0);
polygon[1] = vertex(w,0, s1,t0);
polygon[2] = vertex(w,h, s1,t1);
polygon[3] = vertex(0,h, s0,t1);
triangulate();
}
Geometry::Geometry(const Geometry &other)
: polygon(other.polygon)
, vertexCount(other.vertexCount)
, x_min(other.x_min)
, x_max(other.x_max)
, y_min(other.y_min)
, y_max(other.y_max)
{
vertexArray = new vertex[vertexCount];
memcpy(vertexArray, other.vertexArray, vertexCount * sizeof(vertex));
}
Geometry &Geometry::operator=(const Geometry &other)
{
if (this != &other)
{
Geometry temp(other);
std::swap(polygon, temp.polygon);
std::swap(vertexArray, temp.vertexArray);
vertexCount = temp.vertexCount;
x_min = temp.x_min;
x_max = temp.x_max;
y_min = temp.y_min;
y_max = temp.y_max;
}
return *this;
}
Geometry::~Geometry()
{
if (vertexArray)
{
delete[] vertexArray;
vertexArray = NULL;
}
}
const vertex &Geometry::getVertex(size_t i) const
{
if (i >= polygon.size())
throw Exception("Invalid vertex index");
return polygon[i];
}
void Geometry::setVertex(size_t i, const vertex &v)
{
if (i >= polygon.size())
throw Exception("Invalid vertex index");
polygon[i] = v;
x_min = v.x < x_min ? v.x : x_min;
x_max = v.x > x_max ? v.x : x_max;
y_min = v.y < y_min ? v.y : y_min;
y_max = v.y > y_max ? v.y : y_max;
triangulate();
}
void Geometry::flip(bool x, bool y)
{
for (size_t i = 0; i < vertexCount; ++i)
{
vertex &v = vertexArray[i];
if (x) v.x = x_max + x_min - v.x;
if (y) v.y = y_max + y_min - v.y;
}
}
void Geometry::triangulate()
{
const std::vector<Triangle> triangles = Math::instance.triangulate(polygon);
if (vertexArray)
delete[] vertexArray;
vertexCount = triangles.size() * 3;
vertexArray = new vertex[vertexCount];
for (size_t i = 0; i < triangles.size(); ++i)
{
const Triangle &t = triangles[i];
vertexArray[i*3] = t.a;
vertexArray[i*3+1] = t.b;
vertexArray[i*3+2] = t.c;
}
}
} // graphics
} // love
+107
View File
@@ -0,0 +1,107 @@
/**
* Copyright (c) 2006-2012 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_GRAPHICS_GEOMETRY_H
#define LOVE_GRAPHICS_GEOMETRY_H
// LOVE
#include "common/Object.h"
#include "common/math.h"
// std
#include <vector>
namespace love
{
namespace graphics
{
class Geometry : public Object
{
public:
/**
* Creates a new geometry object from a std::vector<vertex>.
* @param v
**/
Geometry(const std::vector<vertex> &polygon);
/**
* Creates a new geometry from (texture) quad information.
* @param x Top left position in the image.
* @param y Top left position in the image.
* @param w Width of the quad.
* @param h Height of the quad.
* @param sw The reference width, the width of the Image.
* @param sh The reference height, the height of the Image.
*/
Geometry(float x, float y, float w, float h, float sw, float sh);
Geometry(const Geometry &other);
Geometry &operator=(const Geometry &other);
virtual ~Geometry();
/**
* Returns number of vertices in the *polygon* defining the geometry.
**/
size_t getNumVertices() const
{
return polygon.size();
}
const vertex &getVertex(size_t i) const;
void setVertex(size_t i, const vertex &v);
void flip(bool x, bool y);
/**
* Returns a pointer to the vertex array.
**/
const vertex *getVertexArray() const
{
return vertexArray;
}
/**
* Returns the size of the vertex array.
**/
size_t getVertexArraySize() const
{
return vertexCount;
}
private:
void triangulate();
std::vector<vertex> polygon;
vertex *vertexArray;
size_t vertexCount;
float x_min;
float x_max;
float y_min;
float y_max;
};
} // graphics
} // love
#endif // LOVE_GRAPHICS_GEOMETRY_H
+2 -2
View File
@@ -23,7 +23,7 @@
// LOVE
#include "graphics/Volatile.h"
#include "graphics/DrawQable.h"
#include "graphics/DrawGable.h"
#include "common/StringMap.h"
namespace love
@@ -31,7 +31,7 @@ namespace love
namespace graphics
{
class Image : public DrawQable, public Volatile
class Image : public DrawGable, public Volatile
{
public:
+30 -16
View File
@@ -25,6 +25,7 @@
#include "common/config.h"
#include <cstring> // For memcpy
#include <limits>
namespace love
{
@@ -64,7 +65,7 @@ struct FramebufferStrategy
/**
* @param[in] canvases List of canvases to attach
**/
virtual void setAttachments(const std::vector<Canvas *> &canvases) {}
virtual void setAttachments(const std::vector<Canvas *> &canvases) { (void)canvases; }
/// stop using all additional attached canvases
virtual void setAttachments() {}
@@ -155,7 +156,7 @@ struct FramebufferStrategyGL3 : public FramebufferStrategy
drawbuffers.push_back(GL_COLOR_ATTACHMENT0);
// attach the canvas framebuffer textures to the currently bound framebuffer
for (int i = 0; i < canvases.size(); i++)
for (size_t i = 0; i < canvases.size(); i++)
{
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1 + i,
GL_TEXTURE_2D, canvases[i]->getTextureName(), 0);
@@ -258,7 +259,7 @@ struct FramebufferStrategyPackedEXT : public FramebufferStrategy
drawbuffers.push_back(GL_COLOR_ATTACHMENT0_EXT);
// attach the canvas framebuffer textures to the currently bound framebuffer
for (int i = 0; i < canvases.size(); i++)
for (size_t i = 0; i < canvases.size(); i++)
{
glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1_EXT + i,
GL_TEXTURE_2D, canvases[i]->getTextureName(), 0);
@@ -481,7 +482,7 @@ void Canvas::startGrab(const std::vector<Canvas *> &canvases)
if (!isMultiCanvasSupported())
throw love::Exception("Multi-canvas rendering is not supported on this system.");
if (canvases.size()+1 > maxDrawBuffers || canvases.size()+1 > maxFBOColorAttachments)
if (canvases.size()+1 > size_t(maxDrawBuffers) || canvases.size()+1 > size_t(maxFBOColorAttachments))
throw love::Exception("This system can't simultaniously render to %d canvases.", canvases.size()+1);
}
@@ -583,20 +584,27 @@ void Canvas::draw(float x, float y, float angle, float sx, float sy, float ox, f
drawv(t, vertices);
}
void Canvas::drawq(love::graphics::Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const
void Canvas::drawg(love::graphics::Geometry *geom, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const
{
const vertex *v = quad->getVertices();
// mirror quad on x axis
vertex w[4];
memcpy(w, v, sizeof(vertex)*4);
for (size_t i = 0; i < 4; ++i)
w[i].t = 1. - w[i].t;
static Matrix t;
t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky);
drawv(t, w);
// flip texture coordinates vertically
size_t vcount = geom->getVertexArraySize();
const vertex *w = geom->getVertexArray();
vertex *v = new vertex[vcount];
for (size_t i = 0; i < vcount; ++i)
{
v[i] = w[i];
v[i].t = 1. - v[i].t;
}
// use colors stored in geometry (horrible, horrible hack)
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(vertex), (GLvoid *)&v->r);
drawv(t, v, vcount, GL_TRIANGLES);
glDisableClientState(GL_COLOR_ARRAY);
delete[] v;
}
love::image::ImageData *Canvas::getImageData(love::image::Image *image)
@@ -702,7 +710,7 @@ int Canvas::getHeight()
return height;
}
void Canvas::drawv(const Matrix &t, const vertex *v) const
void Canvas::drawv(const Matrix &t, const vertex *v, GLsizei count, GLenum mode) const
{
glPushMatrix();
@@ -712,9 +720,15 @@ void Canvas::drawv(const Matrix &t, const vertex *v) const
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
// XXX: drawg() enables/disables GL_COLOR_ARRAY in order to use the color
// defined in the geometry to draw itself.
// if the drawing method below is changed to use something other than
// glDrawArrays(), drawg() needs to be updated accordingly!
glVertexPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid *)&v[0].x);
glTexCoordPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid *)&v[0].s);
glDrawArrays(GL_QUADS, 0, 4);
glDrawArrays(mode, 0, count);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
+6 -10
View File
@@ -21,8 +21,7 @@
#ifndef LOVE_GRAPHICS_OPENGL_CANVAS_H
#define LOVE_GRAPHICS_OPENGL_CANVAS_H
// LOVE
#include "graphics/DrawQable.h"
#include "graphics/DrawGable.h"
#include "graphics/Volatile.h"
#include "graphics/Image.h"
#include "graphics/Color.h"
@@ -32,9 +31,6 @@
#include "common/Matrix.h"
#include "OpenGL.h"
// STL
#include <vector>
namespace love
{
namespace graphics
@@ -42,7 +38,7 @@ namespace graphics
namespace opengl
{
class Canvas : public DrawQable, public Volatile
class Canvas : public DrawGable, public Volatile
{
public:
enum TextureType {
@@ -67,9 +63,9 @@ public:
virtual void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const;
/**
* @copydoc DrawQable::drawq()
* @copydoc DrawGable::drawg()
**/
void drawq(love::graphics::Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const;
void drawg(love::graphics::Geometry *geom, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const;
love::image::ImageData *getImageData(love::image::Image *image);
@@ -77,7 +73,7 @@ public:
const std::vector<Canvas *> &getAttachedCanvases() const;
void setFilter(const Image::Filter &f);
void setFilter(const Image::Filter &f);
Image::Filter getFilter() const;
void setWrap(const Image::Wrap &w);
@@ -137,7 +133,7 @@ private:
std::vector<Canvas *> attachedCanvases;
void setupGrab();
void drawv(const Matrix &t, const vertex *v) const;
void drawv(const Matrix &t, const vertex *v, GLsizei count = 4, GLenum mode = GL_QUADS) const;
static StringMap<TextureType, TYPE_MAX_ENUM>::Entry textureTypeEntries[];
static StringMap<TextureType, TYPE_MAX_ENUM> textureTypes;
+7 -9
View File
@@ -20,7 +20,7 @@
#include "common/config.h"
#include "Font.h"
#include "font/GlyphData.h"
#include "Quad.h"
#include "modules/graphics/Geometry.h"
#include "Image.h"
#include "libraries/utf8/utf8.h"
@@ -212,14 +212,12 @@ Font::Glyph *Font::addGlyph(unsigned int glyph)
g->texture = t;
Quad::Viewport v;
v.x = (float) textureX;
v.y = (float) textureY;
v.w = (float) w;
v.h = (float) h;
Quad q = Quad(v, (const float) textureWidth, (const float) textureHeight);
const vertex *verts = q.getVertices();
const vertex verts[4] = {
vertex(0, 0, float(textureX)/float(textureWidth), float(textureY)/float(textureHeight)),
vertex(w, 0, float(textureX+w)/float(textureWidth), float(textureY)/float(textureHeight)),
vertex(w, h, float(textureX+w)/float(textureWidth), float(textureY+h)/float(textureHeight)),
vertex(0, h, float(textureX)/float(textureWidth), float(textureY+h)/float(textureHeight)),
};
// copy vertex data to the glyph and set proper bearing
for (int i = 0; i < 4; i++)
+20 -7
View File
@@ -120,6 +120,12 @@ void Graphics::restoreState(const DisplayState &s)
setColorMask(s.colorMask[0], s.colorMask[1], s.colorMask[2], s.colorMask[3]);
}
static void APIENTRY myErrorCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char *message, void *ud)
{
(void)ud;
std::cerr << "source = " << source << ", type = " << type << ", id = " << id << ", severity = " << severity << ", length = " << length << "\n" << message << std::endl;
}
bool Graphics::setMode(int width, int height, WindowFlags *flags)
{
// This operation destroys the OpenGL context, so
@@ -202,6 +208,13 @@ bool Graphics::setMode(int width, int height, WindowFlags *flags)
glGetIntegerv(GL_MAX_MODELVIEW_STACK_DEPTH, &matrixLimit);
matrixLimit -= 5;
if (GLEE_ARB_debug_output)
{
std::cerr << "debug on" << std::endl;
glDebugMessageCallbackARB(myErrorCallback, NULL);
glEnable(GL_DEBUG_OUTPUT);
}
return success;
}
@@ -492,14 +505,14 @@ Image *Graphics::newImage(love::image::CompressedData *cdata)
return image;
}
Quad *Graphics::newQuad(float x, float y, float w, float h, float sw, float sh)
Geometry *Graphics::newGeometry(const std::vector<vertex> &vertices)
{
Quad::Viewport v;
v.x = x;
v.y = y;
v.w = w;
v.h = h;
return new Quad(v, sw, sh);
return new Geometry(vertices);
}
Geometry *Graphics::newQuad(float x, float y, float w, float h, float sw, float sh)
{
return new Geometry(x, y, w, h, sw, sh);
}
Font *Graphics::newFont(love::font::Rasterizer *r, const Image::Filter &filter)
+8 -3
View File
@@ -39,7 +39,7 @@
#include "Font.h"
#include "Image.h"
#include "Quad.h"
#include "graphics/Geometry.h"
#include "SpriteBatch.h"
#include "ParticleSystem.h"
#include "Canvas.h"
@@ -287,9 +287,14 @@ public:
Image *newImage(love::image::CompressedData *cdata);
/**
* Creates a Quad object.
* Creates a Geometry object.
**/
Quad *newQuad(float x, float y, float w, float h, float sw, float sh);
Geometry *newGeometry(const std::vector<vertex> &vertices);
/**
* Creates a quadliteral Geometry object.
**/
Geometry *newQuad(float x, float y, float w, float h, float sw, float sh);
/**
* Creates a Font object.
+17 -6
View File
@@ -101,13 +101,18 @@ void Image::draw(float x, float y, float angle, float sx, float sy, float ox, fl
drawv(t, vertices);
}
void Image::drawq(love::graphics::Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const
void Image::drawg(love::graphics::Geometry *geom, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const
{
static Matrix t;
const vertex *v = quad->getVertices();
t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky);
drawv(t, v);
// use colors stored in geometry (horrible, horrible hack)
const vertex *v = geom->getVertexArray();
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(vertex), (GLvoid *)&v->r);
drawv(t, v, geom->getVertexArraySize(), GL_TRIANGLES);
glDisableClientState(GL_COLOR_ARRAY);
}
void Image::uploadCompressedMipmaps()
@@ -491,7 +496,7 @@ bool Image::refresh()
return true;
}
void Image::drawv(const Matrix &t, const vertex *v) const
void Image::drawv(const Matrix &t, const vertex *v, GLsizei count, GLenum mode) const
{
bind();
@@ -501,9 +506,15 @@ void Image::drawv(const Matrix &t, const vertex *v) const
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
// XXX: drawg() enables/disables GL_COLOR_ARRAY in order to use the color
// defined in the geometry to draw itself.
// if the drawing method below is changed to use something other than
// glDrawArrays(), drawg() needs to be updated accordingly!
glVertexPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid *)&v[0].x);
glTexCoordPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid *)&v[0].s);
glDrawArrays(GL_QUADS, 0, 4);
glDrawArrays(mode, 0, count);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
+3 -3
View File
@@ -82,9 +82,9 @@ public:
void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const;
/**
* @copydoc DrawQable::drawq()
* @copydoc DrawGable::drawg()
**/
void drawq(love::graphics::Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const;
void drawg(love::graphics::Geometry *geom, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const;
/**
* Sets the filter mode.
@@ -137,7 +137,7 @@ public:
private:
void drawv(const Matrix &t, const vertex *v) const;
void drawv(const Matrix &t, const vertex *v, GLsizei count = 4, GLenum mode = GL_QUADS) const;
friend class Shader;
GLuint getTextureName() const
+1 -51
View File
@@ -103,9 +103,6 @@ ParticleSystem::ParticleSystem(Image *image, unsigned int buffer)
ParticleSystem::~ParticleSystem()
{
for (size_t i = 0; i < quads.size(); i++)
quads[i]->release();
if (this->image != 0)
this->image->release();
@@ -528,33 +525,6 @@ std::vector<Color> ParticleSystem::getColor() const
return ncolors;
}
void ParticleSystem::setQuads(const std::vector<Quad *> &newQuads)
{
for (size_t i = 0; i < quads.size(); i++)
quads[i]->release();
quads.resize(newQuads.size());
for (size_t i = 0; i < newQuads.size(); i++)
{
quads[i] = newQuads[i];
quads[i]->retain();
}
}
void ParticleSystem::setQuads()
{
for (size_t i = 0; i < quads.size(); i++)
quads[i]->release();
quads.resize(0);
}
const std::vector<Quad *> &ParticleSystem::getQuads() const
{
return quads;
}
int ParticleSystem::count() const
{
return (int)(pLast - pStart);
@@ -631,21 +601,12 @@ void ParticleSystem::draw(float x, float y, float angle, float sx, float sy, flo
const vertex *imageVerts = image->getVertices();
const vertex *tVerts;
size_t numQuads = quads.size();
// set the vertex data for each particle (transformation, texcoords, color)
for (int i = 0; i < numParticles; i++)
{
particle *p = pStart + i;
if (numQuads > 0)
{
// Make sure the quad index is valid
size_t quadIndex = (p->quadIndex >= numQuads) ? numQuads - 1 : p->quadIndex;
tVerts = quads[quadIndex]->getVertices();
}
else
tVerts = imageVerts;
tVerts = imageVerts;
// particle vertices are image vertices transformed by particle information
t.setTransformation(p->position[0], p->position[1], p->rotation, p->size, p->size, offsetX, offsetY, 0.0f, 0.0f);
@@ -778,17 +739,6 @@ void ParticleSystem::update(float dt)
s -= (float)i; // 0 <= s <= 1
p->color = colors[i] * (1.0f - s) + colors[k] * s;
// Update quad index
k = quads.size();
if (k > 0)
{
s = t * (float) k; // [0:numquads-1]
i = (s > 0) ? (size_t) s : 0;
p->quadIndex = (i < k) ? i : k - 1;
}
else
p->quadIndex = 0;
// Next particle.
p++;
}
+1 -22
View File
@@ -27,7 +27,6 @@
#include "common/Vector.h"
#include "graphics/Drawable.h"
#include "graphics/Color.h"
#include "Quad.h"
#include "Image.h"
#include <vector>
@@ -64,8 +63,6 @@ struct particle
float spinEnd;
Colorf color;
size_t quadIndex;
};
/**
@@ -83,7 +80,7 @@ public:
DISTRIBUTION_NONE,
DISTRIBUTION_UNIFORM,
DISTRIBUTION_NORMAL,
DISTRIBUTION_MAX_ENUM,
DISTRIBUTION_MAX_ENUM
};
/**
@@ -435,22 +432,6 @@ public:
**/
std::vector<Color> getColor() const;
/**
* Sets the quads used when drawing the particles.
* @param newQuads Array of quads.
**/
void setQuads(const std::vector<Quad *> &newQuads);
/**
* Removes all quads from the particle system.
**/
void setQuads();
/**
* Returns the list of quads used when drawing the particles.
**/
const std::vector<Quad *> &getQuads() const;
/**
* Returns the amount of particles that are currently active in the system.
**/
@@ -599,8 +580,6 @@ protected:
// Color.
std::vector<Colorf> colors;
std::vector<Quad *> quads;
void add();
void remove(particle *p);
+8 -9
View File
@@ -25,7 +25,7 @@
// LOVE
#include "Image.h"
#include "Quad.h"
#include "modules/graphics/Geometry.h"
#include "VertexBuffer.h"
namespace love
@@ -118,24 +118,25 @@ int SpriteBatch::add(float x, float y, float a, float sx, float sy, float ox, fl
return index;
}
int SpriteBatch::addq(Quad *quad, float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index /*= -1*/)
int SpriteBatch::addg(Geometry *geom, float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index /*= -1*/)
{
// Only do this if there's a free slot.
if ((index == -1 && next >= size) || index < -1 || index >= next)
return -1;
// Needed for colors.
memcpy(sprite, quad->getVertices(), sizeof(vertex)*4);
size_t vcount = geom->getVertexArraySize();
memcpy(sprite, geom->getVertexArray(), vcount * sizeof(vertex));
// Transform.
Matrix t;
t.setTransformation(x, y, a, sx, sy, ox, oy, kx, ky);
t.transform(sprite, sprite, 4);
t.transform(sprite, sprite, vcount);
if (color)
setColorv(sprite, *color);
addv(sprite, (index == -1) ? next : index);
addv(sprite, (index == -1) ? next : index, vcount);
// Increment counter.
if (index == -1)
@@ -247,12 +248,10 @@ void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float
glPopMatrix();
}
void SpriteBatch::addv(const vertex *v, int index)
void SpriteBatch::addv(const vertex *v, int index, int sprite_size)
{
int sprite_size = sizeof(vertex) * 4;
sprite_size *= sizeof(vertex); // bytecount
VertexBuffer::Bind bind(*array_buf);
array_buf->fill(index * sprite_size, sprite_size, v);
}
+5 -5
View File
@@ -32,6 +32,7 @@
#include "graphics/Drawable.h"
#include "graphics/Volatile.h"
#include "graphics/Color.h"
#include "graphics/Geometry.h"
namespace love
{
@@ -42,7 +43,6 @@ namespace opengl
// Forward declarations.
class Image;
class Quad;
class VertexBuffer;
class VertexIndex;
@@ -62,7 +62,7 @@ public:
virtual ~SpriteBatch();
int add(float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index = -1);
int addq(Quad *quad, float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index = -1);
int addg(Geometry *geom, float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index = -1);
void clear();
void *lock();
@@ -81,7 +81,7 @@ public:
void setColor(const Color &color);
/**
* Disable per-quad colors for this SpriteBatch. The next call to
* Disable per-geometry colors for this SpriteBatch. The next call to
* draw will use the global color for all sprites.
*/
void setColor();
@@ -104,7 +104,7 @@ public:
private:
void addv(const vertex *v, int index);
void addv(const vertex *v, int index, int sprite_size = 4);
/**
* Set the color for vertices.
@@ -129,7 +129,7 @@ private:
vertex sprite[4];
// Current color. This color, if present, will be applied to the next
// added quad.
// added geometry.
Color *color;
VertexBuffer *array_buf;
@@ -0,0 +1,119 @@
/**
* Copyright (c) 2006-2013 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
// LOVE
#include "wrap_Geometry.h"
#include "common/Exception.h"
namespace love
{
namespace graphics
{
namespace opengl
{
Geometry *luax_checkgeometry(lua_State *L, int idx)
{
return luax_checktype<Geometry>(L, idx, "Geometry", GRAPHICS_GEOMETRY_T);
}
// different name than in Geometry.cpp to make the triangulation transparent
int w_Geometry_getVertexCount(lua_State *L)
{
Geometry *geom = luax_checktype<Geometry>(L, 1, "Geometry", GRAPHICS_GEOMETRY_T);
lua_pushinteger(L, geom->getNumVertices());
return 1;
}
int w_Geometry_getVertex(lua_State *L)
{
Geometry *geom = luax_checktype<Geometry>(L, 1, "Geometry", GRAPHICS_GEOMETRY_T);
size_t i = size_t(luaL_checkint(L, 2));
try
{
const vertex &v = geom->getVertex(i-1);
lua_pushnumber(L, v.x);
lua_pushnumber(L, v.y);
lua_pushnumber(L, v.s);
lua_pushnumber(L, v.t);
lua_pushnumber(L, v.r);
lua_pushnumber(L, v.g);
lua_pushnumber(L, v.b);
lua_pushnumber(L, v.a);
}
catch (Exception &e)
{
return luaL_error(L, e.what());
}
return 8;
}
int w_Geometry_setVertex(lua_State *L)
{
Geometry *geom = luax_checktype<Geometry>(L, 1, "Geometry", GRAPHICS_GEOMETRY_T);
size_t i = size_t(luaL_checkint(L, 2));
vertex v;
v.x = luaL_checknumber(L, 3);
v.y = luaL_checknumber(L, 4);
v.s = luaL_checknumber(L, 5);
v.t = luaL_checknumber(L, 6);
v.r = luaL_optint(L, 7, 255);
v.g = luaL_optint(L, 8, 255);
v.b = luaL_optint(L, 9, 255);
v.a = luaL_optint(L, 10, 255);
try
{
geom->setVertex(i-1, v);
}
catch (Exception &e)
{
return luaL_error(L, e.what());
}
return 0;
}
int w_Geometry_flip(lua_State *L)
{
Geometry *geom = luax_checktype<Geometry>(L, 1, "Geometry", GRAPHICS_GEOMETRY_T);
geom->flip(luax_toboolean(L, 2), luax_toboolean(L, 3));
return 0;
}
static const luaL_Reg w_Geometry_functions[] =
{
{ "getVertexCount", w_Geometry_getVertexCount },
{ "getVertex", w_Geometry_getVertex },
{ "setVertex", w_Geometry_setVertex },
{ "flip", w_Geometry_flip },
{ 0, 0 }
};
extern "C" int luaopen_geometry(lua_State *L)
{
return luax_register_type(L, "Geometry", w_Geometry_functions);
}
} // opengl
} // graphics
} // love
@@ -0,0 +1,46 @@
/**
* Copyright (c) 2006-2013 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_GRAPHICS_OPENGL_WRAP_GEOMETRY_H
#define LOVE_GRAPHICS_OPENGL_WRAP_GEOMETRY_H
// LOVE
#include "common/runtime.h"
#include "graphics/Geometry.h"
namespace love
{
namespace graphics
{
namespace opengl
{
Geometry *luax_checkgeometry(lua_State *L, int idx);
int w_Geometry_flip(lua_State *L);
int w_Geometry_getVertexCount(lua_State *L);
int w_Geometry_getVertex(lua_State *L);
int w_Geometry_setVertex(lua_State *L);
extern "C" int luaopen_geometry(lua_State *L);
} // opengl
} // graphics
} // love
#endif // LOVE_GRAPHICS_OPENGL_WRAP_GEOMETRY_H
+68 -11
View File
@@ -20,7 +20,7 @@
#include "wrap_Graphics.h"
#include "OpenGL.h"
#include "graphics/DrawQable.h"
#include "graphics/DrawGable.h"
#include "image/ImageData.h"
#include "font/Rasterizer.h"
@@ -372,6 +372,61 @@ int w_newImage(lua_State *L)
return 1;
}
int w_newGeometry(lua_State *L)
{
std::vector<vertex> vertices;
if (!lua_istable(L, 1))
return luaL_typerror(L, 1, "table");
size_t n = lua_objlen(L, 1);
if (n < 3)
return luaL_error(L, "Need at least three points to construct a geometry.");
vertices.reserve(n);
for (size_t i = 0; i < n; ++i)
{
vertex v;
lua_rawgeti(L, 1, i+1);
if (!lua_istable(L, -1))
return luaL_typerror(L, 1, "table of tables");
lua_rawgeti(L, -1, 1);
v.x = luaL_checknumber(L, -1);
lua_rawgeti(L, -2, 2);
v.y = luaL_checknumber(L, -1);
lua_rawgeti(L, -3, 3);
v.s = luaL_checknumber(L, -1);
lua_rawgeti(L, -4, 4);
v.t = luaL_checknumber(L, -1);
lua_rawgeti(L, -5, 5);
v.r = luaL_optint(L, -1, 255);
lua_rawgeti(L, -6, 6);
v.g = luaL_optint(L, -1, 255);
lua_rawgeti(L, -7, 7);
v.b = luaL_optint(L, -1, 255);
lua_rawgeti(L, -8, 8);
v.a = luaL_optint(L, -1, 255);
lua_pop(L, 9);
vertices.push_back(v);
}
Geometry *geom = instance->newGeometry(vertices);
if (geom == 0)
return luaL_error(L, "Could not create geometry.");
luax_newtype(L, "Geometry", GRAPHICS_GEOMETRY_T, (void *)geom);
return 1;
}
int w_newQuad(lua_State *L)
{
float x = (float) luaL_checknumber(L, 1);
@@ -381,9 +436,9 @@ int w_newQuad(lua_State *L)
float sw = (float) luaL_checknumber(L, 5);
float sh = (float) luaL_checknumber(L, 6);
Quad *quad = instance->newQuad(x, y, w, h, sw, sh);
Geometry *quad = instance->newQuad(x, y, w, h, sw, sh);
luax_newtype(L, "Quad", GRAPHICS_QUAD_T, (void *)quad);
luax_newtype(L, "Geometry", GRAPHICS_GEOMETRY_T, (void *)quad);
return 1;
}
@@ -1064,7 +1119,7 @@ int w_setCanvases(lua_State *L)
canvas = luax_checkcanvas(L, -1);
lua_pop(L, 1);
for (int i = 2; i <= lua_objlen(L, 1); i++)
for (size_t i = 2; i <= lua_objlen(L, 1); i++)
{
lua_rawgeti(L, 1, i);
attachments.push_back(luax_checkcanvas(L, -1));
@@ -1236,7 +1291,7 @@ int w_draw(lua_State *L)
}
/**
* Draws an Quad of a DrawQable at the specified coordinates,
* Draws a portion of a DrawGable at the specified coordinates,
* with rotation and scaling along both axes.
*
* @param q The Quad to draw.
@@ -1250,10 +1305,10 @@ int w_draw(lua_State *L)
* @param kx Shear along the x-axis.
* @param ky Shear along the y-axis.
**/
int w_drawq(lua_State *L)
int w_drawg(lua_State *L)
{
DrawQable *dq = luax_checktype<DrawQable>(L, 1, "DrawQable", GRAPHICS_DRAWQABLE_T);
Quad *q = luax_checkquad(L, 2);
DrawGable *dq = luax_checktype<DrawGable>(L, 1, "DrawGable", GRAPHICS_DRAWGABLE_T);
Geometry *geom = luax_checkgeometry(L, 2);
float x = (float)luaL_optnumber(L, 3, 0.0f);
float y = (float)luaL_optnumber(L, 4, 0.0f);
float angle = (float)luaL_optnumber(L, 5, 0);
@@ -1263,7 +1318,7 @@ int w_drawq(lua_State *L)
float oy = (float)luaL_optnumber(L, 9, 0);
float kx = (float)luaL_optnumber(L, 10, 0);
float ky = (float)luaL_optnumber(L, 11, 0);
dq->drawq(q, x, y, angle, sx, sy, ox, oy, kx, ky);
dq->drawg(geom, x, y, angle, sx, sy, ox, oy, kx, ky);
return 0;
}
@@ -1565,6 +1620,7 @@ static const luaL_Reg functions[] =
{ "newImage", w_newImage },
{ "newQuad", w_newQuad },
{ "newGeometry", w_newGeometry },
{ "newFont", w_newFont },
{ "newImageFont", w_newImageFont },
{ "newSpriteBatch", w_newSpriteBatch },
@@ -1611,7 +1667,8 @@ static const luaL_Reg functions[] =
{ "isSupported", w_isSupported },
{ "draw", w_draw },
{ "drawq", w_drawq },
{ "drawq", w_drawg }, // legacy
{ "drawg", w_drawg },
{ "print", w_print },
{ "printf", w_printf },
@@ -1665,7 +1722,7 @@ static const lua_CFunction types[] =
{
luaopen_font,
luaopen_image,
luaopen_quad,
luaopen_geometry,
luaopen_spritebatch,
luaopen_particlesystem,
luaopen_canvas,
+3 -3
View File
@@ -24,7 +24,7 @@
// LOVE
#include "wrap_Font.h"
#include "wrap_Image.h"
#include "wrap_Quad.h"
#include "wrap_Geometry.h"
#include "wrap_SpriteBatch.h"
#include "wrap_ParticleSystem.h"
#include "wrap_Canvas.h"
@@ -59,7 +59,7 @@ int w_setStencil(lua_State *L);
int w_setAlphaTest(lua_State *L);
int w_getAlphaTest(lua_State *L);
int w_newImage(lua_State *L);
int w_newQuad(lua_State *L);
int w_newGeometry(lua_State *L);
int w_newQuad(lua_State *L);
int w_newFont(lua_State *L);
int w_newImageFont(lua_State *L);
@@ -100,7 +100,7 @@ int w_setShader(lua_State *L);
int w_getShader(lua_State *L);
int w_isSupported(lua_State *L);
int w_draw(lua_State *L);
int w_drawq(lua_State *L);
int w_drawg(lua_State *L);
int w_print(lua_State *L);
int w_printf(lua_State *L);
int w_point(lua_State *L);
@@ -19,7 +19,6 @@
**/
#include "wrap_ParticleSystem.h"
#include "wrap_Quad.h"
#include "common/Vector.h"
@@ -530,58 +529,6 @@ int w_ParticleSystem_getColors(lua_State *L)
return colors.size();
}
int w_ParticleSystem_setQuads(lua_State *L)
{
ParticleSystem *t = luax_checkparticlesystem(L, 1);
int nQuads = lua_gettop(L) - 1;
if (lua_istable(L, 2))
nQuads = lua_objlen(L, 2);
// Remove all quads if no argument is given.
if (nQuads == 0)
{
t->setQuads();
return 0;
}
std::vector<Quad *> quads(nQuads);
if (lua_istable(L, 2))
{
for (int i = 0; i < nQuads; i++)
{
lua_rawgeti(L, 2, i + 1); // array index
quads[i] = luax_checkquad(L, -1);
lua_pop(L, 1);
}
}
else
{
for (int i = 0; i < nQuads; i++)
quads[i] = luax_checkquad(L, i + 2);
}
t->setQuads(quads);
return 0;
}
int w_ParticleSystem_getQuads(lua_State *L)
{
ParticleSystem *t = luax_checkparticlesystem(L, 1);
const std::vector<Quad *> &quads = t->getQuads();
for (size_t i = 0; i < quads.size(); i++)
{
quads[i]->retain();
luax_newtype(L, "Quad", GRAPHICS_QUAD_T, (void *) quads[i]);
}
return quads.size();
}
int w_ParticleSystem_count(lua_State *L)
{
ParticleSystem *t = luax_checkparticlesystem(L, 1);
@@ -698,8 +645,6 @@ static const luaL_Reg functions[] =
{ "getSpinVariation", w_ParticleSystem_getSpinVariation },
{ "setColors", w_ParticleSystem_setColors },
{ "getColors", w_ParticleSystem_getColors },
{ "setQuads", w_ParticleSystem_setQuads },
{ "getQuads", w_ParticleSystem_getQuads },
{ "setOffset", w_ParticleSystem_setOffset },
{ "getOffset", w_ParticleSystem_getOffset },
{ "count", w_ParticleSystem_count },
@@ -76,8 +76,6 @@ int w_ParticleSystem_setSpinVariation(lua_State *L);
int w_ParticleSystem_getSpinVariation(lua_State *L);
int w_ParticleSystem_setColors(lua_State *L);
int w_ParticleSystem_getColors(lua_State *L);
int w_ParticleSystem_setQuads(lua_State *L);
int w_ParticleSystem_getQuads(lua_State *L);
int w_ParticleSystem_setOffset(lua_State *L);
int w_ParticleSystem_getOffset(lua_State *L);
int w_ParticleSystem_count(lua_State *L);
@@ -49,10 +49,11 @@ int w_SpriteBatch_add(lua_State *L)
return 1;
}
int w_SpriteBatch_addq(lua_State *L)
int w_SpriteBatch_addg(lua_State *L)
{
SpriteBatch *t = luax_checkspritebatch(L, 1);
Quad *q = luax_checktype<Quad>(L, 2, "Quad", GRAPHICS_QUAD_T);
Geometry *g = luax_checktype<Geometry>(L, 2, "Geometry", GRAPHICS_GEOMETRY_T);
float x = (float)luaL_optnumber(L, 3, 0.0f);
float y = (float)luaL_optnumber(L, 4, 0.0f);
float angle = (float)luaL_optnumber(L, 5, 0.0f);
@@ -62,7 +63,7 @@ int w_SpriteBatch_addq(lua_State *L)
float oy = (float)luaL_optnumber(L, 9, 0);
float kx = (float)luaL_optnumber(L, 10, 0);
float ky = (float)luaL_optnumber(L, 11, 0);
lua_pushnumber(L, t->addq(q, x, y, angle, sx, sy, ox, oy, kx, ky));
lua_pushnumber(L, t->addg(g, x, y, angle, sx, sy, ox, oy, kx, ky));
return 1;
}
@@ -87,7 +88,8 @@ int w_SpriteBatch_setq(lua_State *L)
{
SpriteBatch *t = luax_checkspritebatch(L, 1);
int index = luaL_checkinteger(L, 2);
Quad *q = luax_checktype<Quad>(L, 3, "Quad", GRAPHICS_QUAD_T);
Geometry *g = luax_checktype<Geometry>(L, 3, "Geometry", GRAPHICS_GEOMETRY_T);
float x = (float)luaL_optnumber(L, 4, 0.0f);
float y = (float)luaL_optnumber(L, 5, 0.0f);
float angle = (float)luaL_optnumber(L, 6, 0.0f);
@@ -97,7 +99,7 @@ int w_SpriteBatch_setq(lua_State *L)
float oy = (float)luaL_optnumber(L, 10, 0);
float kx = (float)luaL_optnumber(L, 11, 0);
float ky = (float)luaL_optnumber(L, 12, 0);
t->addq(q, x, y, angle, sx, sy, ox, oy, kx, ky, index);
t->addg(g, x, y, angle, sx, sy, ox, oy, kx, ky, index);
return 0;
}
@@ -198,7 +200,7 @@ int w_SpriteBatch_isFull(lua_State *L)
static const luaL_Reg functions[] =
{
{ "add", w_SpriteBatch_add },
{ "addq", w_SpriteBatch_addq },
{ "addg", w_SpriteBatch_addg },
{ "set", w_SpriteBatch_set },
{ "setq", w_SpriteBatch_setq },
{ "clear", w_SpriteBatch_clear },
-1
View File
@@ -30,7 +30,6 @@ using love::vertex;
namespace
{
// check if an angle is oriented counter clockwise
inline bool is_oriented_ccw(const vertex &a, const vertex &b, const vertex &c)
{