mirror of
https://github.com/love2d/love.git
synced 2026-08-16 08:11:02 +02:00
Merge in minor branch, now minor is our next development target
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2011 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_COLOR_H
|
||||
#define LOVE_GRAPHICS_COLOR_H
|
||||
|
||||
namespace love
|
||||
{
|
||||
namespace graphics
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
struct ColorT
|
||||
{
|
||||
T r;
|
||||
T g;
|
||||
T b;
|
||||
T a;
|
||||
|
||||
ColorT() : r(0), g(0), b(0), a(0) {}
|
||||
ColorT(T r_, T g_, T b_, T a_) : r(r_), g(g_), b(b_), a(a_) {}
|
||||
void set(T r_, T g_, T b_, T a_) { r = r_; g = g_; b = b_; a = a_; }
|
||||
|
||||
ColorT<T> operator+=(const ColorT<T>& other);
|
||||
ColorT<T> operator*=(T s);
|
||||
ColorT<T> operator/=(T s);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
ColorT<T> ColorT<T>::operator+=(const ColorT<T>& other)
|
||||
{
|
||||
r += other.r;
|
||||
g += other.g;
|
||||
b += other.b;
|
||||
a += other.a;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
ColorT<T> ColorT<T>::operator*=(T s)
|
||||
{
|
||||
r *= s;
|
||||
g *= s;
|
||||
b *= s;
|
||||
a *= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
ColorT<T> ColorT<T>::operator/=(T s)
|
||||
{
|
||||
r /= s;
|
||||
g /= s;
|
||||
b /= s;
|
||||
a /= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
ColorT<T> operator+(const ColorT<T>& a, const ColorT<T>& b)
|
||||
{
|
||||
ColorT<T> tmp(a);
|
||||
return tmp += b;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
ColorT<T> operator*(const ColorT<T>& a, T s)
|
||||
{
|
||||
ColorT<T> tmp(a);
|
||||
return tmp *= s;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
ColorT<T> operator/(const ColorT<T>& a, T s)
|
||||
{
|
||||
ColorT<T> tmp(a);
|
||||
return tmp /= s;
|
||||
}
|
||||
|
||||
typedef ColorT<unsigned char> Color;
|
||||
typedef ColorT<float> Colorf;
|
||||
|
||||
} // graphics
|
||||
} // love
|
||||
|
||||
#endif // LOVE_GRAPHICS_COLOR_H
|
||||
@@ -17,13 +17,18 @@
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
**/
|
||||
|
||||
#include <common/config.h>
|
||||
#include "Font.h"
|
||||
#include <font/GlyphData.h>
|
||||
#include "Quad.h"
|
||||
|
||||
#include <libraries/utf8/utf8.h>
|
||||
|
||||
#include <common/math.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <algorithm> // for max
|
||||
|
||||
namespace love
|
||||
{
|
||||
namespace graphics
|
||||
@@ -31,33 +36,104 @@ namespace graphics
|
||||
namespace opengl
|
||||
{
|
||||
|
||||
Font::Font(love::font::FontData * data, const Image::Filter& filter)
|
||||
: height(data->getHeight()), lineHeight(1), mSpacing(1)
|
||||
Font::Font(love::font::Rasterizer * r, const Image::Filter& filter)
|
||||
: rasterizer(r), height(r->getHeight()), lineHeight(1), mSpacing(1), filter(filter)
|
||||
{
|
||||
glyphs = new Glyph*[MAX_CHARS];
|
||||
type = FONT_UNKNOWN;
|
||||
love::font::GlyphData * gd;
|
||||
|
||||
for(unsigned int i = 0; i < MAX_CHARS; i++)
|
||||
{
|
||||
gd = data->getGlyphData(i);
|
||||
glyphs[i] = new Glyph(gd, filter);
|
||||
glyphs[i]->load();
|
||||
widths[i] = gd->getWidth();
|
||||
spacing[i] = gd->getAdvance();
|
||||
bearingX[i] = gd->getBearingX();
|
||||
bearingY[i] = gd->getBearingY();
|
||||
if (type == FONT_UNKNOWN) type = (gd->getFormat() == love::font::GlyphData::FORMAT_LUMINANCE_ALPHA ? FONT_TRUETYPE : FONT_IMAGE);
|
||||
}
|
||||
r->retain();
|
||||
love::font::GlyphData * gd = r->getGlyphData(32);
|
||||
type = (gd->getFormat() == love::font::GlyphData::FORMAT_LUMINANCE_ALPHA ? FONT_TRUETYPE : FONT_IMAGE);
|
||||
delete gd;
|
||||
createTexture();
|
||||
}
|
||||
|
||||
Font::~Font()
|
||||
{
|
||||
for(unsigned int i = 0; i < MAX_CHARS; i++)
|
||||
{
|
||||
glyphs[i]->release();
|
||||
rasterizer->release();
|
||||
unloadVolatile();
|
||||
}
|
||||
|
||||
void Font::createTexture()
|
||||
{
|
||||
texture_x = texture_y = rowHeight = 0;
|
||||
GLuint t;
|
||||
glGenTextures(1, &t);
|
||||
textures.push_back(t);
|
||||
glBindTexture(GL_TEXTURE_2D, t);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
|
||||
(filter.mag == Image::FILTER_LINEAR) ? GL_LINEAR : GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
||||
(filter.min == Image::FILTER_LINEAR) ? GL_LINEAR : GL_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
GLint format = (type == FONT_TRUETYPE ? GL_LUMINANCE_ALPHA : GL_RGBA);
|
||||
glTexImage2D(GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_RGBA,
|
||||
(GLsizei)TEXTURE_WIDTH,
|
||||
(GLsizei)TEXTURE_HEIGHT,
|
||||
0,
|
||||
format,
|
||||
GL_UNSIGNED_BYTE,
|
||||
NULL);
|
||||
}
|
||||
|
||||
Font::Glyph * Font::addGlyph(int glyph)
|
||||
{
|
||||
Glyph * g = new Glyph;
|
||||
g->list = glGenLists(1);
|
||||
if (g->list == 0) { // opengl failed to generate the list
|
||||
delete g;
|
||||
return NULL;
|
||||
}
|
||||
delete[] glyphs;
|
||||
love::font::GlyphData *gd = rasterizer->getGlyphData(glyph);
|
||||
g->spacing = gd->getAdvance();
|
||||
int w = gd->getWidth();
|
||||
int h = gd->getHeight();
|
||||
if (texture_x + w > TEXTURE_WIDTH) { // out of space - new row!
|
||||
texture_x = 0;
|
||||
texture_y += rowHeight;
|
||||
rowHeight = 0;
|
||||
}
|
||||
if (texture_y + h > TEXTURE_HEIGHT) { // totally out of space - new texture!
|
||||
createTexture();
|
||||
}
|
||||
GLuint t = textures.back();
|
||||
glBindTexture(GL_TEXTURE_2D, t);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, texture_x, texture_y, w, h, (type == FONT_TRUETYPE ? GL_LUMINANCE_ALPHA : GL_RGBA), GL_UNSIGNED_BYTE, gd->getData());
|
||||
|
||||
Quad::Viewport v;
|
||||
v.x = texture_x;
|
||||
v.y = texture_y;
|
||||
v.w = w;
|
||||
v.h = h;
|
||||
Quad * q = new Quad(v, TEXTURE_WIDTH, TEXTURE_HEIGHT);
|
||||
const vertex * verts = q->getVertices();
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid *)&verts[0].x);
|
||||
glTexCoordPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid *)&verts[0].s);
|
||||
|
||||
glNewList(g->list, GL_COMPILE);
|
||||
glBindTexture(GL_TEXTURE_2D, t);
|
||||
glPushMatrix();
|
||||
glTranslatef(static_cast<float>(gd->getBearingX()), static_cast<float>(-gd->getBearingY()), 0.0f);
|
||||
glDrawArrays(GL_QUADS, 0, 4);
|
||||
glPopMatrix();
|
||||
glEndList();
|
||||
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
delete q;
|
||||
delete gd;
|
||||
|
||||
texture_x += w;
|
||||
rowHeight = std::max(rowHeight, h);
|
||||
|
||||
glyphs[glyph] = g;
|
||||
return g;
|
||||
}
|
||||
|
||||
float Font::getHeight() const
|
||||
@@ -65,7 +141,7 @@ namespace opengl
|
||||
return static_cast<float>(height);
|
||||
}
|
||||
|
||||
void Font::print(std::string text, float x, float y, float angle, float sx, float sy) const
|
||||
void Font::print(std::string text, float x, float y, float angle, float sx, float sy)
|
||||
{
|
||||
float dx = 0.0f; // spacing counter for newline handling
|
||||
glPushMatrix();
|
||||
@@ -73,67 +149,82 @@ namespace opengl
|
||||
glTranslatef(ceil(x), ceil(y), 0.0f);
|
||||
glRotatef(LOVE_TODEG(angle), 0, 0, 1.0f);
|
||||
glScalef(sx, sy, 1.0f);
|
||||
for (unsigned int i = 0; i < text.size(); i++) {
|
||||
unsigned char g = (unsigned char)text[i];
|
||||
utf8::iterator<std::string::iterator> i (text.begin(), text.begin(), text.end());
|
||||
utf8::iterator<std::string::iterator> end (text.end(), text.begin(), text.end());
|
||||
while (i != end) {
|
||||
int g = *i++;
|
||||
if (g == '\n') { // wrap newline, but do not print it
|
||||
glTranslatef(-dx, floor(getHeight() * getLineHeight() + 0.5f), 0);
|
||||
dx = 0.0f;
|
||||
continue;
|
||||
}
|
||||
if (!glyphs[g]) g = 32; // space
|
||||
Glyph * glyph = glyphs[g];
|
||||
if (!glyph) glyph = addGlyph(g);
|
||||
glPushMatrix();
|
||||
// 1.25 is magic line height for true type fonts
|
||||
if (type == FONT_TRUETYPE) glTranslatef(0, floor(getHeight() / 1.25f + 0.5f), 0);
|
||||
glyphs[g]->draw(0, 0, 0, 1, 1, 0, 0);
|
||||
glCallList(glyph->list);
|
||||
glPopMatrix();
|
||||
glTranslatef(static_cast<GLfloat>(spacing[g]), 0, 0);
|
||||
dx += spacing[g];
|
||||
glTranslatef(static_cast<GLfloat>(glyph->spacing), 0, 0);
|
||||
dx += glyph->spacing;
|
||||
}
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
void Font::print(char character, float x, float y) const
|
||||
void Font::print(char character, float x, float y)
|
||||
{
|
||||
if (!glyphs[(int)character]) character = ' ';
|
||||
Glyph * glyph = glyphs[character];
|
||||
if (!glyph) glyph = addGlyph(character);
|
||||
glPushMatrix();
|
||||
glTranslatef(x, floor(y+getHeight() + 0.5f), 0.0f);
|
||||
glCallList(list+character);
|
||||
glCallList(glyph->list);
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
int Font::getWidth(const std::string & line) const
|
||||
int Font::getWidth(const std::string & line)
|
||||
{
|
||||
if(line.size() == 0) return 0;
|
||||
int temp = 0;
|
||||
|
||||
Glyph * g;
|
||||
|
||||
for(unsigned int i = 0; i < line.size(); i++)
|
||||
{
|
||||
temp += static_cast<int>((spacing[(int)line[i]] * mSpacing));
|
||||
utf8::iterator<std::string::const_iterator> i (line.begin(), line.begin(), line.end());
|
||||
utf8::iterator<std::string::const_iterator> end (line.end(), line.begin(), line.end());
|
||||
while (i != end) {
|
||||
int c = *i++;
|
||||
g = glyphs[c];
|
||||
if (!g) g = addGlyph(c);
|
||||
temp += static_cast<int>(g->spacing * mSpacing);
|
||||
}
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
int Font::getWidth(const char * line) const
|
||||
int Font::getWidth(const char * line)
|
||||
{
|
||||
return this->getWidth(std::string(line));
|
||||
}
|
||||
|
||||
int Font::getWidth(const char character) const
|
||||
int Font::getWidth(const char character)
|
||||
{
|
||||
return spacing[(int)character];
|
||||
Glyph * g = glyphs[character];
|
||||
if (!g) g = addGlyph(character);
|
||||
return g->spacing;
|
||||
}
|
||||
|
||||
int Font::getWrap(const std::string & line, float wrap, int * lines) const
|
||||
int Font::getWrap(const std::string & line, float wrap, int * lines)
|
||||
{
|
||||
if(line.size() == 0) return 0;
|
||||
int maxw = 0;
|
||||
int linen = 1;
|
||||
int temp = 0;
|
||||
std::string text;
|
||||
Glyph * g;
|
||||
|
||||
for(unsigned int i = 0; i < line.size(); i++)
|
||||
{
|
||||
|
||||
utf8::iterator<std::string::const_iterator> i (line.begin(), line.begin(), line.end());
|
||||
utf8::iterator<std::string::const_iterator> end (line.end(), line.begin(), line.end());
|
||||
while (i != end) {
|
||||
if(temp > wrap && text.find(" ") != std::string::npos)
|
||||
{
|
||||
unsigned int space = text.find_last_of(' ');
|
||||
@@ -144,8 +235,11 @@ namespace opengl
|
||||
temp = getWidth(text);
|
||||
linen++;
|
||||
}
|
||||
temp += static_cast<int>((spacing[(int)line[i]] * mSpacing));
|
||||
text += line[i];
|
||||
int c = *i++;
|
||||
g = glyphs[c];
|
||||
if (!g) g = addGlyph(c);
|
||||
temp += static_cast<int>(g->spacing * mSpacing);
|
||||
utf8::append(c, text.end());
|
||||
}
|
||||
|
||||
if(temp > maxw) maxw = temp;
|
||||
@@ -154,7 +248,7 @@ namespace opengl
|
||||
return maxw;
|
||||
}
|
||||
|
||||
int Font::getWrap(const char * line, float wrap, int * lines) const
|
||||
int Font::getWrap(const char * line, float wrap, int * lines)
|
||||
{
|
||||
return getWrap(std::string(line), wrap, lines);
|
||||
}
|
||||
@@ -181,21 +275,27 @@ namespace opengl
|
||||
|
||||
bool Font::loadVolatile()
|
||||
{
|
||||
// reload all glyphs
|
||||
for(unsigned int i = 0; i < MAX_CHARS; i++)
|
||||
{
|
||||
glyphs[i]->load();
|
||||
glNewList(list + i, GL_COMPILE);
|
||||
glyphs[i]->draw(0, 0, 0, 1, 1, 0, 0);
|
||||
glEndList();
|
||||
}
|
||||
createTexture();
|
||||
return true;
|
||||
}
|
||||
|
||||
void Font::unloadVolatile()
|
||||
{
|
||||
// delete the glyphs
|
||||
glDeleteLists(list, MAX_CHARS);
|
||||
// nuke everything from orbit
|
||||
std::map<int, Glyph *>::iterator it = glyphs.begin();
|
||||
Glyph * g;
|
||||
while (it != glyphs.end()) {
|
||||
g = it->second;
|
||||
glDeleteLists(g->list, 1);
|
||||
delete g;
|
||||
glyphs.erase(it++);
|
||||
}
|
||||
std::vector<GLuint>::iterator iter = textures.begin();
|
||||
while (iter != textures.end()) {
|
||||
glDeleteTextures(1, (GLuint*)&*iter);
|
||||
iter++;
|
||||
}
|
||||
textures.clear();
|
||||
}
|
||||
|
||||
} // opengl
|
||||
|
||||
@@ -22,13 +22,16 @@
|
||||
#define LOVE_GRAPHICS_OPENGL_FONT_H
|
||||
|
||||
// STD
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// LOVE
|
||||
#include <common/Object.h>
|
||||
#include <font/FontData.h>
|
||||
#include <font/Rasterizer.h>
|
||||
#include <graphics/Image.h>
|
||||
#include "Glyph.h"
|
||||
|
||||
#include "GLee.h"
|
||||
|
||||
namespace love
|
||||
{
|
||||
@@ -46,31 +49,40 @@ namespace opengl
|
||||
FONT_IMAGE,
|
||||
FONT_UNKNOWN
|
||||
};
|
||||
|
||||
struct Glyph
|
||||
{
|
||||
GLuint list;
|
||||
int spacing;
|
||||
};
|
||||
|
||||
love::font::Rasterizer * rasterizer;
|
||||
|
||||
int height;
|
||||
float lineHeight;
|
||||
float mSpacing; // modifies the spacing by multiplying it with this value
|
||||
Glyph ** glyphs;
|
||||
GLuint list; // the list of glyphs, for quicker drawing
|
||||
std::vector<GLuint> textures; // vector of packed textures
|
||||
std::map<int, Glyph *> glyphs; // maps glyphs to display lists
|
||||
FontType type;
|
||||
Image::Filter filter;
|
||||
|
||||
static const int TEXTURE_WIDTH = 512;
|
||||
static const int TEXTURE_HEIGHT = 512;
|
||||
|
||||
int texture_x, texture_y;
|
||||
int rowHeight;
|
||||
|
||||
void createTexture();
|
||||
Glyph * addGlyph(int glyph);
|
||||
|
||||
public:
|
||||
static const unsigned int MAX_CHARS = 256;
|
||||
// The widths of each character.
|
||||
int widths[MAX_CHARS];
|
||||
// The spacing of each character.
|
||||
int spacing[MAX_CHARS];
|
||||
// The X-bearing of each character.
|
||||
int bearingX[MAX_CHARS];
|
||||
// The Y-bearing of each character.
|
||||
int bearingY[MAX_CHARS];
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*
|
||||
* @param data The font data to construct from.
|
||||
**/
|
||||
Font(love::font::FontData * data, const Image::Filter& filter = Image::Filter());
|
||||
Font(love::font::Rasterizer * r, const Image::Filter& filter = Image::Filter());
|
||||
|
||||
virtual ~Font();
|
||||
|
||||
@@ -82,7 +94,7 @@ namespace opengl
|
||||
* @param y The y-coordinate.
|
||||
* @param angle The amount of rotation.
|
||||
**/
|
||||
void print(std::string text, float x, float y, float angle = 0.0f, float sx = 1.0f, float sy = 1.0f) const;
|
||||
void print(std::string text, float x, float y, float angle = 0.0f, float sx = 1.0f, float sy = 1.0f);
|
||||
|
||||
/**
|
||||
* Prints the character at the designated position.
|
||||
@@ -91,7 +103,7 @@ namespace opengl
|
||||
* @param x The x-coordinate.
|
||||
* @param y The y-coordinate.
|
||||
**/
|
||||
void print(char character, float x, float y) const;
|
||||
void print(char character, float x, float y);
|
||||
|
||||
/**
|
||||
* Returns the height of the font.
|
||||
@@ -103,15 +115,15 @@ namespace opengl
|
||||
*
|
||||
* @param line A line of text.
|
||||
**/
|
||||
int getWidth(const std::string & line) const;
|
||||
int getWidth(const char * line) const;
|
||||
int getWidth(const std::string & line);
|
||||
int getWidth(const char * line);
|
||||
|
||||
/**
|
||||
* Returns the width of the passed character.
|
||||
*
|
||||
* @param character A character.
|
||||
**/
|
||||
int getWidth(const char character) const;
|
||||
int getWidth(const char character);
|
||||
|
||||
/**
|
||||
* Returns the maximal width of a wrapped string
|
||||
@@ -121,8 +133,8 @@ namespace opengl
|
||||
* @param wrap The number of pixels to wrap at
|
||||
* @param lines Optional output of the number of lines needed
|
||||
**/
|
||||
int getWrap(const std::string & line, float wrap, int *lines = 0) const;
|
||||
int getWrap(const char * line, float wrap, int *lines = 0) const;
|
||||
int getWrap(const std::string & line, float wrap, int *lines = 0);
|
||||
int getWrap(const char * line, float wrap, int *lines = 0);
|
||||
|
||||
/**
|
||||
* Sets the line height (which should be a number to multiply the font size by,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "Framebuffer.h"
|
||||
#include "Graphics.h"
|
||||
#include <common/Matrix.h>
|
||||
|
||||
#include <cstring> // For memcpy
|
||||
@@ -199,10 +200,9 @@ namespace opengl
|
||||
current->stopGrab();
|
||||
|
||||
// bind buffer and clear screen
|
||||
glPushAttrib(GL_VIEWPORT_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_TRANSFORM_BIT);
|
||||
glPushAttrib(GL_VIEWPORT_BIT | GL_DEPTH_BUFFER_BIT | GL_TRANSFORM_BIT);
|
||||
strategy->bindFBO(fbo);
|
||||
glClearColor(.0f, .0f, .0f, .0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
// Reset the projection matrix
|
||||
@@ -234,6 +234,22 @@ namespace opengl
|
||||
current = NULL;
|
||||
}
|
||||
|
||||
|
||||
void Framebuffer::clear(const Color& c)
|
||||
{
|
||||
GLuint previous = 0;
|
||||
if (current != NULL)
|
||||
previous = current->fbo;
|
||||
|
||||
strategy->bindFBO(fbo);
|
||||
glPushAttrib(GL_COLOR_BUFFER_BIT);
|
||||
glClearColor((float)c.r/255.0f, (float)c.g/255.0f, (float)c.b/255.0f, (float)c.a/255.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glPopAttrib();
|
||||
|
||||
strategy->bindFBO(previous);
|
||||
}
|
||||
|
||||
void Framebuffer::draw(float x, float y, float angle, float sx, float sy, float ox, float oy) const
|
||||
{
|
||||
static Matrix t;
|
||||
@@ -343,6 +359,9 @@ namespace opengl
|
||||
|
||||
setFilter(settings.filter);
|
||||
setWrap(settings.wrap);
|
||||
Color c;
|
||||
c.r = c.g = c.b = c.a = 0;
|
||||
clear(c);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <graphics/Drawable.h>
|
||||
#include <graphics/Volatile.h>
|
||||
#include <graphics/Image.h>
|
||||
#include <graphics/Color.h>
|
||||
#include <image/Image.h>
|
||||
#include <image/ImageData.h>
|
||||
#include <common/math.h>
|
||||
@@ -29,6 +30,8 @@ namespace opengl
|
||||
void startGrab();
|
||||
void stopGrab();
|
||||
|
||||
void clear(const Color& c);
|
||||
|
||||
virtual void draw(float x, float y, float angle, float sx, float sy, float ox, float oy) const;
|
||||
love::image::ImageData * getImageData(love::image::Image * image);
|
||||
|
||||
|
||||
@@ -1,147 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2011 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 "Glyph.h"
|
||||
|
||||
// STD
|
||||
#include <cstring> // For memcpy
|
||||
|
||||
namespace love
|
||||
{
|
||||
namespace graphics
|
||||
{
|
||||
namespace opengl
|
||||
{
|
||||
|
||||
Glyph::Glyph(love::font::GlyphData * data, const Image::Filter& filter_)
|
||||
: data(data),
|
||||
width((float)data->getWidth()), height((float)data->getHeight()),
|
||||
texture(0), filter(filter_)
|
||||
{
|
||||
data->retain();
|
||||
|
||||
memset(vertices, 255, sizeof(vertex)*4);
|
||||
|
||||
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;
|
||||
|
||||
vertices[0].s = 0; vertices[0].t = 0;
|
||||
vertices[1].s = 0; vertices[1].t = 1;
|
||||
vertices[2].s = 1; vertices[2].t = 1;
|
||||
vertices[3].s = 1; vertices[3].t = 0;
|
||||
|
||||
}
|
||||
|
||||
Glyph::~Glyph()
|
||||
{
|
||||
if(data != 0)
|
||||
data->release();
|
||||
unload();
|
||||
}
|
||||
|
||||
void Glyph::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);
|
||||
|
||||
if(texture != 0)
|
||||
glBindTexture(GL_TEXTURE_2D,texture);
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
glMultMatrixf((const GLfloat*)t.getElements());
|
||||
glTranslatef(static_cast<float>(data->getBearingX()), static_cast<float>(-data->getBearingY()), 0.0f);
|
||||
|
||||
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();
|
||||
|
||||
}
|
||||
|
||||
bool Glyph::load()
|
||||
{
|
||||
return loadVolatile();
|
||||
}
|
||||
|
||||
void Glyph::unload()
|
||||
{
|
||||
unloadVolatile();
|
||||
}
|
||||
|
||||
bool Glyph::loadVolatile()
|
||||
{
|
||||
GLint format = GL_RGBA;
|
||||
if (data->getFormat() == love::font::GlyphData::FORMAT_LUMINANCE_ALPHA) format = GL_LUMINANCE_ALPHA;
|
||||
|
||||
glGenTextures(1,&texture);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
|
||||
(filter.mag == Image::FILTER_LINEAR) ? GL_LINEAR : GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
||||
(filter.min == Image::FILTER_LINEAR) ? GL_LINEAR : GL_NEAREST);
|
||||
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_RGBA,
|
||||
(GLsizei)width,
|
||||
(GLsizei)height,
|
||||
0,
|
||||
format,
|
||||
GL_UNSIGNED_BYTE,
|
||||
data->getData());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Glyph::unloadVolatile()
|
||||
{
|
||||
// Delete the hardware texture.
|
||||
if(texture != 0)
|
||||
{
|
||||
glDeleteTextures(1, (GLuint*)&texture);
|
||||
texture = 0;
|
||||
}
|
||||
}
|
||||
|
||||
float Glyph::getWidth() const
|
||||
{
|
||||
return width;
|
||||
}
|
||||
|
||||
float Glyph::getHeight() const
|
||||
{
|
||||
return height;
|
||||
}
|
||||
|
||||
} // opengl
|
||||
} // graphics
|
||||
} // love
|
||||
@@ -1,82 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2011 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_GLYPH_H
|
||||
#define LOVE_GRAPHICS_OPENGL_GLYPH_H
|
||||
|
||||
// LOVE
|
||||
#include <common/config.h>
|
||||
#include <common/math.h>
|
||||
#include <common/Matrix.h>
|
||||
#include <font/GlyphData.h>
|
||||
#include <graphics/Drawable.h>
|
||||
#include <graphics/Volatile.h>
|
||||
#include <graphics/Image.h>
|
||||
|
||||
// OpenGL
|
||||
#include "GLee.h"
|
||||
#include <SDL/SDL_opengl.h>
|
||||
|
||||
namespace love
|
||||
{
|
||||
namespace graphics
|
||||
{
|
||||
namespace opengl
|
||||
{
|
||||
|
||||
class Glyph : public Drawable, public Volatile
|
||||
{
|
||||
private:
|
||||
|
||||
love::font::GlyphData * data;
|
||||
|
||||
float width, height;
|
||||
|
||||
GLuint texture;
|
||||
|
||||
vertex vertices[4];
|
||||
|
||||
Image::Filter filter;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
Glyph(love::font::GlyphData * data, const Image::Filter& filter_ = Image::Filter());
|
||||
virtual ~Glyph();
|
||||
|
||||
bool load();
|
||||
void unload();
|
||||
|
||||
// Implements Volatile.
|
||||
bool loadVolatile();
|
||||
void unloadVolatile();
|
||||
|
||||
float getWidth() const;
|
||||
float getHeight() const;
|
||||
|
||||
void draw(float x, float y, float angle, float sx, float sy, float ox, float oy) const;
|
||||
|
||||
}; // Glyph
|
||||
|
||||
} // opengl
|
||||
} // graphics
|
||||
} // love
|
||||
|
||||
#endif // LOVE_GRAPHICS_OPENGL_GLYPH_H
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include <common/config.h>
|
||||
#include <common/math.h>
|
||||
#include <common/Vector.h>
|
||||
|
||||
#include "Graphics.h"
|
||||
|
||||
@@ -36,7 +37,7 @@ namespace opengl
|
||||
{
|
||||
|
||||
Graphics::Graphics()
|
||||
: currentFont(0)
|
||||
: currentFont(0), lineWidth(1)
|
||||
{
|
||||
// Indicates that there is no screen
|
||||
// created yet.
|
||||
@@ -81,16 +82,10 @@ namespace opengl
|
||||
float color[4];
|
||||
//get the color
|
||||
glGetFloatv(GL_CURRENT_COLOR, color);
|
||||
s.color.r = (GLubyte)(color[0]*255.0f);
|
||||
s.color.g = (GLubyte)(color[1]*255.0f);
|
||||
s.color.b = (GLubyte)(color[2]*255.0f);
|
||||
s.color.a = (GLubyte)(color[3]*255.0f);
|
||||
s.color.set( (color[0]*255.0f), (color[1]*255.0f), (color[2]*255.0f), (color[3]*255.0f) );
|
||||
//get the background color
|
||||
glGetFloatv(GL_COLOR_CLEAR_VALUE, color);
|
||||
s.backgroundColor.r = (GLubyte)(color[0]*255.0f);
|
||||
s.backgroundColor.g = (GLubyte)(color[1]*255.0f);
|
||||
s.backgroundColor.b = (GLubyte)(color[2]*255.0f);
|
||||
s.backgroundColor.a = (GLubyte)(color[3]*255.0f);
|
||||
s.backgroundColor.set( color[0]*255.0f, color[1]*255.0f, color[2]*255.0f, color[3]*255.0f );
|
||||
//store modes here
|
||||
GLint mode;
|
||||
//get blend mode
|
||||
@@ -100,19 +95,8 @@ namespace opengl
|
||||
//get color mode
|
||||
glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &mode);
|
||||
s.colorMode = (mode == GL_MODULATE) ? Graphics::COLOR_MODULATE : Graphics::COLOR_REPLACE;
|
||||
//get the line width (directly to corresponding variable)
|
||||
glGetFloatv(GL_LINE_WIDTH, &s.lineWidth);
|
||||
//get line style
|
||||
s.lineStyle = (glIsEnabled(GL_LINE_SMOOTH) == GL_TRUE) ? Graphics::LINE_SMOOTH : Graphics::LINE_ROUGH;
|
||||
//get line stipple
|
||||
s.stipple = (glIsEnabled(GL_LINE_STIPPLE) == GL_TRUE);
|
||||
if (s.stipple)
|
||||
{
|
||||
//get the stipple repeat
|
||||
glGetIntegerv(GL_LINE_STIPPLE_REPEAT, &s.stippleRepeat);
|
||||
//get the stipple pattern
|
||||
glGetIntegerv(GL_LINE_STIPPLE_PATTERN, &s.stipplePattern);
|
||||
}
|
||||
s.lineStyle = (glIsEnabled(GL_POLYGON_SMOOTH) == GL_TRUE) ? Graphics::LINE_SMOOTH : Graphics::LINE_ROUGH;
|
||||
//get the point size
|
||||
glGetFloatv(GL_POINT_SIZE, &s.pointSize);
|
||||
//get point style
|
||||
@@ -136,11 +120,7 @@ namespace opengl
|
||||
setBackgroundColor(s.backgroundColor);
|
||||
setBlendMode(s.blendMode);
|
||||
setColorMode(s.colorMode);
|
||||
setLine(s.lineWidth, s.lineStyle);
|
||||
if (s.stipple)
|
||||
setLineStipple(s.stipplePattern, s.stippleRepeat);
|
||||
else
|
||||
setLineStipple();
|
||||
setLine(lineWidth, s.lineStyle);
|
||||
setPoint(s.pointSize, s.pointStyle);
|
||||
if (s.scissor)
|
||||
setScissor(s.scissorBox[0], s.scissorBox[1], s.scissorBox[2], s.scissorBox[3]);
|
||||
@@ -193,6 +173,7 @@ namespace opengl
|
||||
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||
SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, (vsync ? 1 : 0));
|
||||
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1);
|
||||
|
||||
// FSAA
|
||||
if(fsaa > 0)
|
||||
@@ -260,8 +241,7 @@ namespace opengl
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
// Enable line/point smoothing.
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
|
||||
setLineStyle(LINE_SMOOTH);
|
||||
glEnable(GL_POINT_SMOOTH);
|
||||
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
|
||||
|
||||
@@ -281,6 +261,9 @@ namespace opengl
|
||||
// Reset modelview matrix
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
// Set pixel row alignment
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
|
||||
|
||||
// Set the new display mode as the current display mode.
|
||||
currentMode.width = width;
|
||||
@@ -314,6 +297,8 @@ namespace opengl
|
||||
void Graphics::reset()
|
||||
{
|
||||
DisplayState s;
|
||||
discardMask();
|
||||
Framebuffer::bindDefaultBuffer();
|
||||
restoreState(s);
|
||||
}
|
||||
|
||||
@@ -443,6 +428,28 @@ namespace opengl
|
||||
return 4;
|
||||
}
|
||||
|
||||
void Graphics::defineMask()
|
||||
{
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glClear(GL_STENCIL_BUFFER_BIT);
|
||||
glStencilFunc(GL_ALWAYS, 1, 1);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
}
|
||||
|
||||
void Graphics::useMask()
|
||||
{
|
||||
glStencilFunc(GL_EQUAL, 1, 1);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
}
|
||||
|
||||
void Graphics::discardMask()
|
||||
{
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
}
|
||||
|
||||
Image * Graphics::newImage(love::image::ImageData * data)
|
||||
{
|
||||
// Create the image.
|
||||
@@ -472,9 +479,9 @@ namespace opengl
|
||||
return new Quad(v, sw, sh);
|
||||
}
|
||||
|
||||
Font * Graphics::newFont(love::font::FontData * data, const Image::Filter& filter)
|
||||
Font * Graphics::newFont(love::font::Rasterizer * r, const Image::Filter& filter)
|
||||
{
|
||||
Font * font = new Font(data, filter);
|
||||
Font * font = new Font(r, filter);
|
||||
|
||||
// Load it and check for errors.
|
||||
if(!font)
|
||||
@@ -501,7 +508,7 @@ namespace opengl
|
||||
return new Framebuffer(width, height);
|
||||
}
|
||||
|
||||
void Graphics::setColor(Color c)
|
||||
void Graphics::setColor(const Color& c)
|
||||
{
|
||||
glColor4ubv(&c.r);
|
||||
}
|
||||
@@ -520,9 +527,9 @@ namespace opengl
|
||||
return t;
|
||||
}
|
||||
|
||||
void Graphics::setBackgroundColor(Color c)
|
||||
void Graphics::setBackgroundColor(const Color& c)
|
||||
{
|
||||
glClearColor((float)c.r/255.0f, (float)c.g/255.0f, (float)c.b/255.0f, 1.0f);
|
||||
glClearColor((float)c.r/255.0f, (float)c.g/255.0f, (float)c.b/255.0f, (float)c.a/255.0f);
|
||||
}
|
||||
|
||||
Color Graphics::getBackgroundColor()
|
||||
@@ -610,45 +617,30 @@ namespace opengl
|
||||
|
||||
void Graphics::setLineWidth( float width )
|
||||
{
|
||||
glLineWidth(width);
|
||||
lineWidth = width;
|
||||
}
|
||||
|
||||
void Graphics::setLineStyle(Graphics::LineStyle style )
|
||||
{
|
||||
// XXX: actually enables antialiasing for _all_ polygons.
|
||||
// may need investigation if wanted or not
|
||||
// maybe rename to something else?
|
||||
if(style == LINE_ROUGH)
|
||||
glDisable (GL_LINE_SMOOTH);
|
||||
glDisable (GL_POLYGON_SMOOTH);
|
||||
else // type == LINE_SMOOTH
|
||||
{
|
||||
glEnable (GL_LINE_SMOOTH);
|
||||
glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);
|
||||
glEnable (GL_POLYGON_SMOOTH);
|
||||
glHint (GL_POLYGON_SMOOTH_HINT, GL_NICEST);
|
||||
}
|
||||
}
|
||||
|
||||
void Graphics::setLine( float width, Graphics::LineStyle style )
|
||||
{
|
||||
glLineWidth(width);
|
||||
setLineWidth(width);
|
||||
|
||||
if(style == 0)
|
||||
return;
|
||||
|
||||
if(style == LINE_ROUGH)
|
||||
glDisable (GL_LINE_SMOOTH);
|
||||
else // type == LINE_SMOOTH
|
||||
{
|
||||
glEnable (GL_LINE_SMOOTH);
|
||||
glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);
|
||||
}
|
||||
}
|
||||
|
||||
void Graphics::setLineStipple()
|
||||
{
|
||||
glDisable(GL_LINE_STIPPLE);
|
||||
}
|
||||
|
||||
void Graphics::setLineStipple(unsigned short pattern, int repeat)
|
||||
{
|
||||
glEnable(GL_LINE_STIPPLE);
|
||||
glLineStipple((GLint)repeat, (GLshort)pattern);
|
||||
setLineStyle(style);
|
||||
}
|
||||
|
||||
float Graphics::getLineWidth()
|
||||
@@ -660,25 +652,12 @@ namespace opengl
|
||||
|
||||
Graphics::LineStyle Graphics::getLineStyle()
|
||||
{
|
||||
if(glIsEnabled(GL_LINE_SMOOTH) == GL_TRUE)
|
||||
if(glIsEnabled(GL_POLYGON_SMOOTH) == GL_TRUE)
|
||||
return LINE_SMOOTH;
|
||||
else
|
||||
return LINE_ROUGH;
|
||||
}
|
||||
|
||||
int Graphics::getLineStipple(lua_State * L)
|
||||
{
|
||||
if(glIsEnabled(GL_LINE_STIPPLE) == GL_FALSE)
|
||||
return 0;
|
||||
|
||||
GLint factor, pattern;
|
||||
glGetIntegerv(GL_LINE_STIPPLE_PATTERN, &pattern);
|
||||
glGetIntegerv(GL_LINE_STIPPLE_REPEAT, &factor);
|
||||
lua_pushinteger(L, pattern);
|
||||
lua_pushinteger(L, factor);
|
||||
return 2;
|
||||
}
|
||||
|
||||
void Graphics::setPointSize( float size )
|
||||
{
|
||||
glPointSize((GLfloat)size);
|
||||
@@ -807,251 +786,168 @@ namespace opengl
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
void Graphics::line( float x1, float y1, float x2, float y2 )
|
||||
// calculate line boundary intersection vertices for current line
|
||||
// dependent on the current *and next* line segment
|
||||
static void pushIntersectionPoints(Vector *vertices, int pos, float halfwidth, const Vector& p, const Vector& q, const Vector& r)
|
||||
{
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glPushMatrix();
|
||||
glBegin(GL_LINES);
|
||||
glVertex2f(x1, y1);
|
||||
glVertex2f(x2, y2);
|
||||
glEnd();
|
||||
glPopMatrix();
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
// calculate line directions
|
||||
Vector s = (q - p);
|
||||
Vector t = (r - q);
|
||||
|
||||
// calculate vertex displacement vectors
|
||||
Vector d1 = s.getNormal();
|
||||
Vector d2 = t.getNormal();
|
||||
d1.normalize();
|
||||
d2.normalize();
|
||||
float det_norm = d1 ^ d2;
|
||||
d1 *= halfwidth;
|
||||
d2 *= halfwidth;
|
||||
|
||||
// lines parallel -> assume intersection at displacement points
|
||||
if (fabs(det_norm) <= .03) {
|
||||
vertices[pos] = q - d2;
|
||||
vertices[pos + 1] = q + d2;
|
||||
return;
|
||||
}
|
||||
|
||||
// real intersection -> calculate boundary intersection points
|
||||
float det = s ^ t;
|
||||
Vector d = d1 - d2;
|
||||
Vector b = s - d; // s = q - p
|
||||
Vector c = s + d;
|
||||
float lambda = (b ^ t) / det;
|
||||
float mu = (c ^ t) / det;
|
||||
|
||||
// ordering for GL_TRIANGLE_STRIP
|
||||
vertices[pos] = p - d1 + s * mu;
|
||||
vertices[pos+1] = p + d1 + s * lambda;
|
||||
}
|
||||
|
||||
int Graphics::polyline( lua_State * L)
|
||||
void Graphics::polyline(const float* coords, size_t count, bool looping)
|
||||
{
|
||||
// Get number of params.
|
||||
int args = lua_gettop(L);
|
||||
bool table = false;
|
||||
Vector *vertices = new Vector[count]; // two vertices for every line end-point
|
||||
Vector p,q,r;
|
||||
|
||||
if (args == 1) { // we've got a table, hopefully
|
||||
int type = lua_type(L, 1);
|
||||
if (type != LUA_TTABLE)
|
||||
return luaL_error(L, "Function requires a table or series of numbers");
|
||||
table = true;
|
||||
args = lua_objlen(L, 1);
|
||||
r = Vector(coords[0], coords[1]);
|
||||
if (looping) q = Vector(coords[count-4], coords[count-3]);
|
||||
else q = r * 2 - Vector(coords[2], coords[3]);
|
||||
|
||||
for (size_t i = 0; i+3 < count; i += 2) {
|
||||
p = q;
|
||||
q = r;
|
||||
r = Vector(coords[i+2], coords[i+3]);
|
||||
pushIntersectionPoints(vertices, i, lineWidth/2, p,q,r);
|
||||
}
|
||||
|
||||
if (args % 2) // an odd number of arguments, no good for a polyline
|
||||
return luaL_error(L, "Number of vertices must be a multiple of two");
|
||||
else if (args < 4)
|
||||
return luaL_error(L, "Need at least two vertices to draw a line");
|
||||
p = q;
|
||||
q = r;
|
||||
if (looping) r = Vector(coords[2], coords[3]);
|
||||
else r += (q-p);
|
||||
pushIntersectionPoints(vertices, count-2, lineWidth/2, p,q,r);
|
||||
|
||||
// right, let's draw this polyline, then
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glBegin(GL_LINE_STRIP);
|
||||
if (table) {
|
||||
for (int i = 1; i < args; i += 2) {
|
||||
lua_pushnumber(L, i); // x coordinate
|
||||
lua_rawget(L, 1);
|
||||
lua_pushnumber(L, i+1); // y coordinate
|
||||
lua_rawget(L, 1);
|
||||
glVertex2f((GLfloat)lua_tonumber(L, -2), (GLfloat)lua_tonumber(L, -1));
|
||||
lua_pop(L, 2);
|
||||
}
|
||||
} else {
|
||||
for (int i = 1; i < args; i+=2) {
|
||||
glVertex2f((GLfloat)lua_tonumber(L, i), (GLfloat)lua_tonumber(L, i+1));
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glVertexPointer(2, GL_FLOAT, 0, (const GLvoid*)vertices);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, count);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
return 0;
|
||||
|
||||
delete[] vertices;
|
||||
}
|
||||
|
||||
void Graphics::triangle(DrawMode mode, float x1, float y1, float x2, float y2, float x3, float y3 )
|
||||
{
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glPushMatrix();
|
||||
|
||||
switch(mode)
|
||||
{
|
||||
case DRAW_LINE:
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2f(x1, y1);
|
||||
glVertex2f(x2, y2);
|
||||
glVertex2f(x3, y3);
|
||||
glEnd();
|
||||
break;
|
||||
|
||||
default:
|
||||
case DRAW_FILL:
|
||||
glBegin(GL_TRIANGLES);
|
||||
glVertex2f(x1, y1);
|
||||
glVertex2f(x2, y2);
|
||||
glVertex2f(x3, y3);
|
||||
glEnd();
|
||||
break;
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
float coords[] = { x1,y1, x2,y2, x3,y3, x1,y1 };
|
||||
polygon(mode, coords, 4 * 2);
|
||||
}
|
||||
|
||||
void Graphics::rectangle(DrawMode mode, float x, float y, float w, float h)
|
||||
{
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glPushMatrix();
|
||||
|
||||
switch(mode)
|
||||
{
|
||||
case DRAW_LINE:
|
||||
// offsets here because OpenGL is being a bitch about line drawings
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2f(x, y);
|
||||
glVertex2f(x, y+h-1);
|
||||
glVertex2f(x+w-1, y+h-1);
|
||||
glVertex2f(x+w-1, y);
|
||||
glEnd();
|
||||
break;
|
||||
|
||||
default:
|
||||
case DRAW_FILL:
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2f(x, y);
|
||||
glVertex2f(x, y+h);
|
||||
glVertex2f(x+w, y+h);
|
||||
glVertex2f(x+w, y);
|
||||
glEnd();
|
||||
break;
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
quad(mode, x,y, x,y+h, x+w,y+h, x+w,y);
|
||||
}
|
||||
|
||||
void Graphics::quad(DrawMode mode, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4 )
|
||||
{
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glPushMatrix();
|
||||
|
||||
switch(mode)
|
||||
{
|
||||
case DRAW_LINE:
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2f(x1, y1);
|
||||
glVertex2f(x2, y2);
|
||||
glVertex2f(x3, y3);
|
||||
glVertex2f(x4, y4);
|
||||
glEnd();
|
||||
break;
|
||||
|
||||
default:
|
||||
case DRAW_FILL:
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2f(x1, y1);
|
||||
glVertex2f(x2, y2);
|
||||
glVertex2f(x3, y3);
|
||||
glVertex2f(x4, y4);
|
||||
glEnd();
|
||||
break;
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
float coords[] = { x1,y1, x2,y2, x3,y3, x4,y4, x1,y1 };
|
||||
polygon(mode, coords, 5 * 2);
|
||||
}
|
||||
|
||||
void Graphics::circle(DrawMode mode, float x, float y, float radius, int points )
|
||||
void Graphics::circle(DrawMode mode, float x, float y, float radius, int points)
|
||||
{
|
||||
float two_pi = static_cast<float>(LOVE_M_PI * 2);
|
||||
if(points <= 0) points = 1;
|
||||
float angle_shift = (two_pi / points);
|
||||
float phi = .0f;
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glPushMatrix();
|
||||
|
||||
glTranslatef(x, y, 0.0f);
|
||||
|
||||
switch(mode)
|
||||
{
|
||||
case DRAW_LINE:
|
||||
glBegin(GL_LINE_LOOP);
|
||||
|
||||
for(float i = 0; i < two_pi; i+= angle_shift)
|
||||
glVertex2f(radius * sin(i),radius * cos(i));
|
||||
|
||||
glEnd();
|
||||
break;
|
||||
|
||||
default:
|
||||
case DRAW_FILL:
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
|
||||
for(float i = 0; i < two_pi; i+= angle_shift)
|
||||
glVertex2f(radius * sin(i),radius * cos(i));
|
||||
|
||||
glEnd();
|
||||
break;
|
||||
float *coords = new float[2 * (points + 1)];
|
||||
for (int i = 0; i < points; ++i, phi += angle_shift) {
|
||||
coords[2*i] = x + radius * cos(phi);
|
||||
coords[2*i+1] = y + radius * sin(phi);
|
||||
}
|
||||
|
||||
coords[2*points] = coords[0];
|
||||
coords[2*points+1] = coords[1];
|
||||
|
||||
polygon(mode, coords, (points + 1) * 2);
|
||||
|
||||
delete[] coords;
|
||||
}
|
||||
|
||||
void Graphics::arc(DrawMode mode, float x, float y, float radius, float angle1, float angle2, int points)
|
||||
{
|
||||
angle1 = fmod(angle1, 2.0f * (float)LOVE_M_PI);
|
||||
angle2 = fmod(angle2, 2.0f * (float)LOVE_M_PI);
|
||||
if (angle1 == angle2)
|
||||
return;
|
||||
else if (angle1 > angle2)
|
||||
angle2 += (float)LOVE_M_PI * 2.0f;
|
||||
|
||||
|
||||
if(points <= 0) points = 1;
|
||||
float angle_shift = ((angle2 - angle1) / points);
|
||||
float phi = angle1;
|
||||
|
||||
// GL_POLYGON can only fill-draw convex polygons, so we need to do stuff manually here
|
||||
if (mode == DRAW_LINE) {
|
||||
float *coords = new float[(points + 3) * 2];
|
||||
coords[0] = coords[2 * points + 4] = x;
|
||||
coords[1] = coords[2 * points + 5] = y;
|
||||
for (int i = 0; i <= points; ++i, phi += angle_shift) {
|
||||
coords[2 * (i+1)] = x + radius * cos(phi);
|
||||
coords[2 * (i+1) + 1] = y - radius * sin(phi);
|
||||
}
|
||||
polyline(coords, (points + 3) * 2); // artifacts at sharp angles if set to looping
|
||||
|
||||
delete[] coords;
|
||||
} else {
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
glVertex2f(x, y);
|
||||
for (int i = 0; i <= points; ++i, phi += angle_shift)
|
||||
glVertex2f(x + radius * cos(phi), y - radius * sin(phi));
|
||||
glEnd();
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
int Graphics::polygon( lua_State * L )
|
||||
/// @param mode the draw mode
|
||||
/// @param coords the coordinate array
|
||||
/// @param count the number of coordinates/size of the array
|
||||
void Graphics::polygon(DrawMode mode, const float* coords, size_t count)
|
||||
{
|
||||
// Get number of params.
|
||||
int n = lua_gettop(L);
|
||||
|
||||
// Need at least two params.
|
||||
if( n < 2 )
|
||||
return luaL_error(L, "Error: function needs at least two parameters.");
|
||||
|
||||
DrawMode mode;
|
||||
|
||||
const char * str = luaL_checkstring(L, 1);
|
||||
if(!getConstant(str, mode))
|
||||
return luaL_error(L, "Invalid draw mode: %s", str);
|
||||
|
||||
// Get the type of the second argument.
|
||||
int luatype = lua_type(L, 2);
|
||||
|
||||
// Perform additional type checking.
|
||||
switch(luatype)
|
||||
{
|
||||
case LUA_TNUMBER:
|
||||
if( n-1 < 6 ) return luaL_error(L, "Error: function requires at least 3 vertices.");
|
||||
if( ((n-1)%2) != 0 ) return luaL_error(L, "Error: number of vertices must be a multiple of two.");
|
||||
break;
|
||||
case LUA_TTABLE:
|
||||
if( (lua_objlen(L, 2)%2) != 0 ) return luaL_error(L, "Error: number of vertices must be a multiple of two.");
|
||||
break;
|
||||
default:
|
||||
return luaL_error(L, "Error: number type or table expected.");
|
||||
// coords is an array of a closed loop of vertices, i.e.
|
||||
// coords[count-2] = coords[0], coords[count-1] = coords[1]
|
||||
if (mode == DRAW_LINE) {
|
||||
polyline(coords, count, true);
|
||||
} else {
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glVertexPointer(2, GL_FLOAT, 0, (const GLvoid*)coords);
|
||||
glDrawArrays(GL_POLYGON, 0, count/2-1); // opengl will close the polygon for us
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
glBegin((mode==DRAW_LINE) ? GL_LINE_LOOP : GL_POLYGON);
|
||||
|
||||
switch(luatype)
|
||||
{
|
||||
case LUA_TNUMBER:
|
||||
for(int i = 2; i<n; i+=2)
|
||||
glVertex2f((GLfloat)lua_tonumber(L, i), (GLfloat)lua_tonumber(L, i+1));
|
||||
break;
|
||||
case LUA_TTABLE:
|
||||
lua_pushnil(L);
|
||||
while (true)
|
||||
{
|
||||
if(lua_next(L, 2) == 0) break;
|
||||
GLfloat x = (GLfloat)lua_tonumber(L, -1);
|
||||
lua_pop(L, 1); // pop value
|
||||
if(lua_next(L, 2) == 0) break;
|
||||
GLfloat y = (GLfloat)lua_tonumber(L, -1);
|
||||
lua_pop(L, 1); // pop value
|
||||
glVertex2f(x, y);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
glEnd();
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
love::image::ImageData * Graphics::newScreenshot(love::image::Image * image)
|
||||
|
||||
@@ -28,12 +28,10 @@
|
||||
// SDL
|
||||
#include <SDL.h>
|
||||
#include "GLee.h"
|
||||
#include <SDL_opengl.h>
|
||||
|
||||
// LOVE
|
||||
#include <graphics/Graphics.h>
|
||||
|
||||
#include <font/FontData.h>
|
||||
#include <graphics/Color.h>
|
||||
|
||||
#include <image/Image.h>
|
||||
#include <image/ImageData.h>
|
||||
@@ -51,10 +49,6 @@ namespace graphics
|
||||
{
|
||||
namespace opengl
|
||||
{
|
||||
struct Color
|
||||
{
|
||||
unsigned char r, g, b, a;
|
||||
};
|
||||
|
||||
struct DisplayMode
|
||||
{
|
||||
@@ -79,11 +73,7 @@ namespace opengl
|
||||
Graphics::ColorMode colorMode;
|
||||
|
||||
// Line.
|
||||
float lineWidth;
|
||||
Graphics::LineStyle lineStyle;
|
||||
bool stipple;
|
||||
GLint stippleRepeat;
|
||||
GLint stipplePattern;
|
||||
|
||||
// Point.
|
||||
float pointSize;
|
||||
@@ -100,19 +90,14 @@ namespace opengl
|
||||
// Default values.
|
||||
DisplayState()
|
||||
{
|
||||
color.r = 255;
|
||||
color.g = 255;
|
||||
color.b = 255;
|
||||
color.a = 255;
|
||||
color.set(255,255,255,255);
|
||||
backgroundColor.r = 0;
|
||||
backgroundColor.g = 0;
|
||||
backgroundColor.b = 0;
|
||||
backgroundColor.a = 255;
|
||||
blendMode = Graphics::BLEND_ALPHA;
|
||||
colorMode = Graphics::COLOR_MODULATE;
|
||||
lineWidth = 1.0f;
|
||||
lineStyle = Graphics::LINE_SMOOTH;
|
||||
stipple = false;
|
||||
pointSize = 1.0f;
|
||||
pointStyle = Graphics::POINT_SMOOTH;
|
||||
scissor = false;
|
||||
@@ -129,6 +114,8 @@ namespace opengl
|
||||
Font * currentFont;
|
||||
DisplayMode currentMode;
|
||||
|
||||
float lineWidth;
|
||||
|
||||
public:
|
||||
|
||||
Graphics();
|
||||
@@ -247,6 +234,22 @@ namespace opengl
|
||||
**/
|
||||
int getScissor(lua_State * L);
|
||||
|
||||
/**
|
||||
* Enables the stencil buffer and set stencil function to fill it
|
||||
*/
|
||||
void defineMask();
|
||||
|
||||
/**
|
||||
* Set stencil function to mask the following drawing calls using
|
||||
* the current stencil buffer
|
||||
*/
|
||||
void useMask();
|
||||
|
||||
/**
|
||||
* Disables the stencil buffer
|
||||
*/
|
||||
void discardMask();
|
||||
|
||||
/**
|
||||
* Creates an Image object with padding and/or optimization.
|
||||
**/
|
||||
@@ -261,7 +264,7 @@ namespace opengl
|
||||
/**
|
||||
* Creates a Font object.
|
||||
**/
|
||||
Font * newFont(love::font::FontData * data, const Image::Filter& filter = Image::Filter());
|
||||
Font * newFont(love::font::Rasterizer * data, const Image::Filter& filter = Image::Filter());
|
||||
|
||||
SpriteBatch * newSpriteBatch(Image * image, int size, int usage);
|
||||
|
||||
@@ -272,7 +275,7 @@ namespace opengl
|
||||
/**
|
||||
* Sets the foreground color.
|
||||
**/
|
||||
void setColor(Color c);
|
||||
void setColor(const Color& c);
|
||||
|
||||
/**
|
||||
* Gets current color.
|
||||
@@ -282,7 +285,7 @@ namespace opengl
|
||||
/**
|
||||
* Sets the background Color.
|
||||
**/
|
||||
void setBackgroundColor(Color c);
|
||||
void setBackgroundColor(const Color& c);
|
||||
|
||||
/**
|
||||
* Gets the current background color.
|
||||
@@ -338,16 +341,6 @@ namespace opengl
|
||||
**/
|
||||
void setLine(float width, LineStyle style);
|
||||
|
||||
/**
|
||||
* Disables line stippling.
|
||||
**/
|
||||
void setLineStipple();
|
||||
|
||||
/**
|
||||
* Sets a line stipple pattern.
|
||||
**/
|
||||
void setLineStipple(unsigned short pattern, int repeat = 1);
|
||||
|
||||
/**
|
||||
* Gets the line width.
|
||||
**/
|
||||
@@ -358,13 +351,6 @@ namespace opengl
|
||||
**/
|
||||
LineStyle getLineStyle();
|
||||
|
||||
/**
|
||||
* Gets the line stipple pattern and repeat factor.
|
||||
* @return pattern The stipplie bit-pattern.
|
||||
* @return repeat The reapeat factor.
|
||||
**/
|
||||
int getLineStipple(lua_State * L);
|
||||
|
||||
/**
|
||||
* Sets the size of points.
|
||||
**/
|
||||
@@ -426,20 +412,13 @@ namespace opengl
|
||||
**/
|
||||
void point(float x, float y);
|
||||
|
||||
/**
|
||||
* Draws a line from (x1,y1) to (x2,y2).
|
||||
* @param x1 First x-coordinate.
|
||||
* @param y1 First y-coordinate.
|
||||
* @param x2 Second x-coordinate.
|
||||
* @param y2 Second y-coordinate.
|
||||
**/
|
||||
void line(float x1, float y1, float x2, float y2);
|
||||
|
||||
/**
|
||||
* Draws a series of lines connecting the given vertices.
|
||||
* @param ... Vertex components (x1, y1, x2, y2, etc.)
|
||||
* @param coords Vertex components (x1, y1, x2, y2, etc.)
|
||||
* @param count Coord array size
|
||||
* @param looping Wether the line is joining itself
|
||||
**/
|
||||
int polyline(lua_State * L);
|
||||
void polyline(const float* coords, size_t count, bool looping = false);
|
||||
|
||||
/**
|
||||
* Draws a triangle using the three coordinates passed.
|
||||
@@ -485,13 +464,16 @@ namespace opengl
|
||||
* @param points Amount of points to use to draw the circle.
|
||||
**/
|
||||
void circle(DrawMode mode, float x, float y, float radius, int points = 10);
|
||||
|
||||
void arc(DrawMode mode, float x, float y, float radius, float angle1, float angle2, int points = 10);
|
||||
|
||||
/**
|
||||
* Draws a polygon with an arbitrary number of vertices.
|
||||
* @param type The type of drawing (line/filled).
|
||||
* @param ... Vertex components (x1, y1, x2, y2, etc).
|
||||
* @param coords Vertex components (x1, y1, x2, y2, etc.)
|
||||
* @param count Coord array size
|
||||
**/
|
||||
int polygon(lua_State * L);
|
||||
void polygon(DrawMode mode, const float* coords, size_t count);
|
||||
|
||||
/**
|
||||
* Creates a screenshot of the view and saves it to the default folder.
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include <SDL_opengl.h>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
namespace love
|
||||
{
|
||||
@@ -34,6 +33,13 @@ namespace graphics
|
||||
namespace opengl
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
Colorf colorToFloat(const Color& c) {
|
||||
return Colorf( (GLfloat)c.r/255.0f, (GLfloat)c.g/255.0f, (GLfloat)c.b/255.0f, (GLfloat)c.a/255.0f );
|
||||
}
|
||||
}
|
||||
|
||||
float calculate_variation(float inner, float outer, float var)
|
||||
{
|
||||
float low = inner - (outer/2.0f)*var;
|
||||
@@ -48,14 +54,14 @@ namespace opengl
|
||||
direction(0), spread(0), relative(false), speedMin(0), speedMax(0), gravityMin(0),
|
||||
gravityMax(0), radialAccelerationMin(0), radialAccelerationMax(0),
|
||||
tangentialAccelerationMin(0), tangentialAccelerationMax(0),
|
||||
sizeStart(1), sizeEnd(1), sizeVariation(0), rotationMin(0), rotationMax(0),
|
||||
sizeVariation(0), rotationMin(0), rotationMax(0),
|
||||
spinStart(0), spinEnd(0), spinVariation(0), offsetX(sprite->getWidth()*0.5f),
|
||||
offsetY(sprite->getHeight()*0.5f)
|
||||
{
|
||||
this->sprite = sprite;
|
||||
sprite->retain();
|
||||
memset(colorStart, 255, 4);
|
||||
memset(colorEnd, 255, 4);
|
||||
sizes.push_back(1.0f);
|
||||
colors.push_back( Colorf(1.0f, 1.0f, 1.0f, 1.0f) );
|
||||
setBufferSize(buffer);
|
||||
}
|
||||
|
||||
@@ -107,9 +113,9 @@ namespace opengl
|
||||
max = tangentialAccelerationMax;
|
||||
pLast->tangentialAcceleration = (rand() / (float(RAND_MAX)+1)) * (max - min) + min;
|
||||
|
||||
pLast->sizeStart = calculate_variation(sizeStart, sizeEnd, sizeVariation);
|
||||
pLast->sizeEnd = calculate_variation(sizeEnd, sizeStart, sizeVariation);
|
||||
pLast->size = pLast->sizeStart;
|
||||
pLast->sizeOffset = (rand() / (float(RAND_MAX)+1)) * sizeVariation; // time offset for size change
|
||||
pLast->sizeIntervalSize = (1.0 - (rand() / (float(RAND_MAX)+1)) * sizeVariation) - pLast->sizeOffset;
|
||||
pLast->size = sizes[(size_t)(pLast->sizeOffset - .5f) * (sizes.size() - 1)];
|
||||
|
||||
min = rotationMin;
|
||||
max = rotationMax;
|
||||
@@ -117,10 +123,7 @@ namespace opengl
|
||||
pLast->spinEnd = calculate_variation(spinEnd, spinStart, spinVariation);
|
||||
pLast->rotation = (rand() / (float(RAND_MAX)+1)) * (max - min) + min;;
|
||||
|
||||
pLast->color[0] = (float)colorStart[0] / 255;
|
||||
pLast->color[1] = (float)colorStart[1] / 255;
|
||||
pLast->color[2] = (float)colorStart[2] / 255;
|
||||
pLast->color[3] = (float)colorStart[3] / 255;
|
||||
pLast->color = colors[0];
|
||||
|
||||
pLast++;
|
||||
}
|
||||
@@ -237,20 +240,13 @@ namespace opengl
|
||||
|
||||
void ParticleSystem::setSize(float size)
|
||||
{
|
||||
sizeStart = size;
|
||||
sizeEnd = size;
|
||||
sizes.resize(1);
|
||||
sizes[0] = size;
|
||||
}
|
||||
|
||||
void ParticleSystem::setSize(float start, float end)
|
||||
void ParticleSystem::setSize(const std::vector<float>& newSizes, float variation)
|
||||
{
|
||||
sizeStart = start;
|
||||
sizeEnd = end;
|
||||
}
|
||||
|
||||
void ParticleSystem::setSize(float start, float end, float variation)
|
||||
{
|
||||
sizeStart = start;
|
||||
sizeEnd = end;
|
||||
sizes = newSizes;
|
||||
sizeVariation = variation;
|
||||
}
|
||||
|
||||
@@ -294,16 +290,17 @@ namespace opengl
|
||||
spinVariation = variation;
|
||||
}
|
||||
|
||||
void ParticleSystem::setColor(unsigned char * color)
|
||||
void ParticleSystem::setColor(const Color& color)
|
||||
{
|
||||
memcpy(colorStart, color, 4);
|
||||
memcpy(colorEnd, color, 4);
|
||||
colors.resize(1);
|
||||
colors[0] = colorToFloat(color);
|
||||
}
|
||||
|
||||
void ParticleSystem::setColor(unsigned char * start, unsigned char * end)
|
||||
void ParticleSystem::setColor(const std::vector<Color>& newColors)
|
||||
{
|
||||
memcpy(colorStart, start, 4);
|
||||
memcpy(colorEnd, end, 4);
|
||||
colors.resize( newColors.size() );
|
||||
for (size_t i = 0; i < newColors.size(); ++i)
|
||||
colors[i] = colorToFloat( newColors[i] );
|
||||
}
|
||||
|
||||
void ParticleSystem::setOffset(float x, float y)
|
||||
@@ -403,12 +400,8 @@ namespace opengl
|
||||
{
|
||||
glPushMatrix();
|
||||
|
||||
glColor4f(p->color[0],p->color[1],p->color[2],p->color[3]);
|
||||
glTranslatef(p->position[0],p->position[1],0.0f);
|
||||
glRotatef(LOVE_TODEG(p->rotation), 0.0f, 0.0f, 1.0f); // rad * (180 / pi)
|
||||
glScalef(p->size,p->size,1.0f);
|
||||
glTranslatef(-offsetX,-offsetY,0.0f);
|
||||
sprite->draw(0,0, 0, 1, 1, 0, 0);
|
||||
glColor4f(p->color.r, p->color.g, p->color.b, p->color.a);
|
||||
sprite->draw(p->position[0], p->position[1], p->rotation, p->size, p->size, offsetX, offsetY);
|
||||
|
||||
glPopMatrix();
|
||||
p++;
|
||||
@@ -481,19 +474,32 @@ namespace opengl
|
||||
p->position[0] = ppos.getX();
|
||||
p->position[1] = ppos.getY();
|
||||
|
||||
const float t = p->life / p->lifetime;
|
||||
|
||||
// Change size.
|
||||
p->size = p->sizeEnd - ((p->sizeEnd - p->sizeStart) * t);
|
||||
const float t = 1.0f - p->life / p->lifetime;
|
||||
|
||||
// Rotate.
|
||||
p->rotation += (p->spinStart*(1-t) + p->spinEnd*t)*dt;
|
||||
p->rotation += (p->spinStart * (1.0f - t) + p->spinEnd * t)*dt;
|
||||
|
||||
// Update color.
|
||||
p->color[0] = (float)(colorEnd[0]*(1.0f-t) + colorStart[0] * t)/255.0f;
|
||||
p->color[1] = (float)(colorEnd[1]*(1.0f-t) + colorStart[1] * t)/255.0f;
|
||||
p->color[2] = (float)(colorEnd[2]*(1.0f-t) + colorStart[2] * t)/255.0f;
|
||||
p->color[3] = (float)(colorEnd[3]*(1.0f-t) + colorStart[3] * t)/255.0f;
|
||||
// Change size according to given intervals:
|
||||
// i = 0 1 2 3 n-1
|
||||
// |-------|-------|------|--- ... ---|
|
||||
// t = 0 1/(n-1) 3/(n-1) 1
|
||||
//
|
||||
// `s' is the interpolation variable scaled to the current
|
||||
// interval width, e.g. if n = 5 and t = 0.3, then the current
|
||||
// indices are 1,2 and s = 0.3 - 0.25 = 0.05
|
||||
float s = p->sizeOffset + t * p->sizeIntervalSize; // size variation
|
||||
s *= (float)(sizes.size() - 1); // 0 <= s < sizes.size()
|
||||
size_t i = (size_t)s;
|
||||
size_t k = (i == sizes.size() - 1) ? i : i + 1; // boundary check (prevents failing on t = 1.0f)
|
||||
s -= (float)i; // transpose s to be in interval [0:1]: i <= s < i + 1 ~> 0 <= s < 1
|
||||
p->size = sizes[i] * (1.0f - t) + sizes[k] * t;
|
||||
|
||||
// Update color according to given intervals (as above)
|
||||
s = t * (float)(colors.size() - 1);
|
||||
i = (size_t)s;
|
||||
k = (i == colors.size() - 1) ? i : i + 1;
|
||||
s -= (float)i; // 0 <= s <= 1
|
||||
p->color = colors[i] * (1.0f - s) + colors[k] * s;
|
||||
|
||||
// Next particle.
|
||||
p++;
|
||||
|
||||
@@ -26,7 +26,9 @@
|
||||
#include <common/math.h>
|
||||
#include <common/Vector.h>
|
||||
#include <graphics/Drawable.h>
|
||||
#include <graphics/Color.h>
|
||||
#include "Image.h"
|
||||
#include <vector>
|
||||
|
||||
namespace love
|
||||
{
|
||||
@@ -50,14 +52,14 @@ namespace opengl
|
||||
float tangentialAcceleration;
|
||||
|
||||
float size;
|
||||
float sizeStart;
|
||||
float sizeEnd;
|
||||
float sizeOffset;
|
||||
float sizeIntervalSize;
|
||||
|
||||
float rotation;
|
||||
float spinStart;
|
||||
float spinEnd;
|
||||
|
||||
float color[4];
|
||||
Colorf color;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -127,8 +129,7 @@ namespace opengl
|
||||
float tangentialAccelerationMax;
|
||||
|
||||
// Size.
|
||||
float sizeStart;
|
||||
float sizeEnd;
|
||||
std::vector<float> sizes;
|
||||
float sizeVariation;
|
||||
|
||||
// Rotation
|
||||
@@ -145,8 +146,7 @@ namespace opengl
|
||||
float offsetY;
|
||||
|
||||
// Color.
|
||||
unsigned char colorStart[4];
|
||||
unsigned char colorEnd[4];
|
||||
std::vector<Colorf> colors;
|
||||
|
||||
void add();
|
||||
void remove(particle * p);
|
||||
@@ -278,20 +278,12 @@ namespace opengl
|
||||
**/
|
||||
void setSize(float size);
|
||||
|
||||
/**
|
||||
* Sets the size of the sprite upon creation and upon death (1.0 being the default size).
|
||||
* @param start The size of the sprite upon creation
|
||||
* @param end The size of the sprite upon death.
|
||||
**/
|
||||
void setSize(float start, float end);
|
||||
|
||||
/**
|
||||
* Sets the size of the sprite upon creation and upon death (1.0 being the default size) and any variation.
|
||||
* @param start The size of the sprite upon creation
|
||||
* @param end The size of the sprite upon death.
|
||||
* @param newSizes Array of sizes
|
||||
* @param variation The amount of variation on the starting size (0 being no variation and 1.0 a random size between start and end).
|
||||
**/
|
||||
void setSize(float start, float end, float variation);
|
||||
void setSize(const std::vector<float>& newSizes, float variation = 0.0f);
|
||||
|
||||
/**
|
||||
* Sets the amount of variation to the sprite's beginning size (0 being no variation and 1.0 a random size between start and end).
|
||||
@@ -343,7 +335,7 @@ namespace opengl
|
||||
* Sets the color of the particles.
|
||||
* @param color The color.
|
||||
**/
|
||||
void setColor(unsigned char * color);
|
||||
void setColor(const Color& color);
|
||||
|
||||
/**
|
||||
* Sets the particles' offsets for rotation.
|
||||
@@ -354,10 +346,9 @@ namespace opengl
|
||||
|
||||
/**
|
||||
* Sets the color of the particles.
|
||||
* @param start The color of the particle when created.
|
||||
* @param end The color of the particle upon death.
|
||||
* @param newColors Array of colors
|
||||
**/
|
||||
void setColor(unsigned char * start, unsigned char * end);
|
||||
void setColor(const std::vector<Color>& newColors);
|
||||
|
||||
/**
|
||||
* Returns the x-coordinate of the emitter's position.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "Graphics.h"
|
||||
#include "wrap_Framebuffer.h"
|
||||
|
||||
namespace love
|
||||
@@ -105,6 +106,40 @@ namespace opengl
|
||||
return 2;
|
||||
}
|
||||
|
||||
int w_Framebuffer_clear(lua_State * L)
|
||||
{
|
||||
Framebuffer * fbo = luax_checkfbo(L, 1);
|
||||
Color c;
|
||||
if (lua_isnoneornil(L, 2)) {
|
||||
c.r = 0;
|
||||
c.g = 0;
|
||||
c.b = 0;
|
||||
c.a = 0;
|
||||
} else if (lua_istable(L, 2)) {
|
||||
lua_pushinteger(L, 1);
|
||||
lua_gettable(L, 2);
|
||||
c.r = (unsigned char)luaL_checkint(L, -1);
|
||||
lua_pushinteger(L, 2);
|
||||
lua_gettable(L, 2);
|
||||
c.g = (unsigned char)luaL_checkint(L, -1);
|
||||
lua_pushinteger(L, 3);
|
||||
lua_gettable(L, 2);
|
||||
c.b = (unsigned char)luaL_checkint(L, -1);
|
||||
lua_pushinteger(L, 4);
|
||||
lua_gettable(L, 2);
|
||||
c.g = (unsigned char)luaL_optint(L, -1, 255);
|
||||
lua_pop(L, 4);
|
||||
} else {
|
||||
c.r = (unsigned char)luaL_checkint(L, 2);
|
||||
c.g = (unsigned char)luaL_checkint(L, 3);
|
||||
c.b = (unsigned char)luaL_checkint(L, 4);
|
||||
c.a = (unsigned char)luaL_optint(L, 5, 255);
|
||||
}
|
||||
fbo->clear(c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const luaL_Reg functions[] = {
|
||||
{ "renderTo", w_Framebuffer_renderTo },
|
||||
{ "getImageData", w_Framebuffer_getImageData },
|
||||
@@ -112,6 +147,7 @@ namespace opengl
|
||||
{ "getFilter", w_Framebuffer_getFilter },
|
||||
{ "setWrap", w_Framebuffer_setWrap },
|
||||
{ "getWrap", w_Framebuffer_getWrap },
|
||||
{ "clear", w_Framebuffer_clear },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace opengl
|
||||
int w_Framebuffer_getFilter(lua_State * L);
|
||||
int w_Framebuffer_setWrap(lua_State * L);
|
||||
int w_Framebuffer_getWrap(lua_State * L);
|
||||
int w_Framebuffer_clear(lua_State * L);
|
||||
int luaopen_framebuffer(lua_State * L);
|
||||
|
||||
} // opengl
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2011 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_Glyph.h"
|
||||
|
||||
namespace love
|
||||
{
|
||||
namespace graphics
|
||||
{
|
||||
namespace opengl
|
||||
{
|
||||
Glyph * luax_checkglyph(lua_State * L, int idx)
|
||||
{
|
||||
return luax_checktype<Glyph>(L, idx, "Glyph", GRAPHICS_GLYPH_T);
|
||||
}
|
||||
|
||||
static const luaL_Reg functions[] = {
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
int luaopen_glyph(lua_State * L)
|
||||
{
|
||||
luax_register_type(L, "Glyph", functions);
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // opengl
|
||||
} // graphics
|
||||
} // love
|
||||
@@ -1,41 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2011 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_GLYPH_H
|
||||
#define LOVE_GRAPHICS_OPENGL_WRAP_GLYPH_H
|
||||
|
||||
// LOVE
|
||||
#include <common/runtime.h>
|
||||
#include "Glyph.h"
|
||||
|
||||
namespace love
|
||||
{
|
||||
namespace graphics
|
||||
{
|
||||
namespace opengl
|
||||
{
|
||||
Glyph * luax_checkglyph(lua_State * L, int idx);
|
||||
int luaopen_glyph(lua_State * L);
|
||||
|
||||
} // opengl
|
||||
} // graphics
|
||||
} // love
|
||||
|
||||
#endif // LOVE_GRAPHICS_OPENGL_WRAP_GLYPH_H
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
#include <image/ImageData.h>
|
||||
#include <font/Rasterizer.h>
|
||||
#include <font/FontData.h>
|
||||
|
||||
#include <scripts/graphics.lua.h>
|
||||
|
||||
@@ -145,6 +144,33 @@ namespace opengl
|
||||
return instance->getScissor(L);
|
||||
}
|
||||
|
||||
int w_defineMask(lua_State * L)
|
||||
{
|
||||
// just return the function
|
||||
if (!lua_isfunction(L, 1))
|
||||
return luaL_typerror(L, 1, "function");
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_setMask(lua_State * L)
|
||||
{
|
||||
// no argument -> clear mask
|
||||
if (lua_isnoneornil(L, 1)) {
|
||||
instance->discardMask();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!lua_isfunction(L, 1))
|
||||
return luaL_typerror(L, 1, "mask");
|
||||
|
||||
instance->defineMask();
|
||||
lua_call(L, lua_gettop(L) - 1, 0); // call mask(...)
|
||||
instance->useMask();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_newImage(lua_State * L)
|
||||
{
|
||||
// Convert to File, if necessary.
|
||||
@@ -175,20 +201,6 @@ namespace opengl
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_newGlyph(lua_State * L)
|
||||
{
|
||||
love::font::GlyphData * data = luax_checktype<love::font::GlyphData>(L, 1, "GlyphData", FONT_GLYPH_DATA_T);
|
||||
|
||||
// Create the image.
|
||||
Glyph * t = new Glyph(data);
|
||||
t->load();
|
||||
|
||||
// Push the type.
|
||||
luax_newtype(L, "Glyph", GRAPHICS_GLYPH_T, (void*)t);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_newQuad(lua_State * L)
|
||||
{
|
||||
int x = luaL_checkint(L, 1);
|
||||
@@ -234,14 +246,10 @@ namespace opengl
|
||||
luax_convobj(L, idxs, 2, "font", "newRasterizer");
|
||||
}
|
||||
|
||||
// Convert to FontData, if necessary.
|
||||
if(luax_istype(L, 1, FONT_RASTERIZER_T))
|
||||
luax_convobj(L, 1, "font", "newFontData");
|
||||
|
||||
love::font::FontData * data = luax_checktype<love::font::FontData>(L, 1, "FontData", FONT_FONT_DATA_T);
|
||||
love::font::Rasterizer * rasterizer = luax_checktype<love::font::Rasterizer>(L, 1, "Rasterizer", FONT_RASTERIZER_T);
|
||||
|
||||
// Create the font.
|
||||
Font * font = instance->newFont(data);
|
||||
Font * font = instance->newFont(rasterizer);
|
||||
|
||||
if(font == 0)
|
||||
return luaL_error(L, "Could not load font.");
|
||||
@@ -274,14 +282,10 @@ namespace opengl
|
||||
luax_convobj(L, idxs, 2, "font", "newRasterizer");
|
||||
}
|
||||
|
||||
// Convert to FontData, if necessary.
|
||||
if(luax_istype(L, 1, FONT_RASTERIZER_T))
|
||||
luax_convobj(L, 1, "font", "newFontData");
|
||||
|
||||
love::font::FontData * data = luax_checktype<love::font::FontData>(L, 1, "FontData", FONT_FONT_DATA_T);
|
||||
love::font::Rasterizer * rasterizer = luax_checktype<love::font::Rasterizer>(L, 1, "Rasterizer", FONT_RASTERIZER_T);
|
||||
|
||||
// Create the font.
|
||||
Font * font = instance->newFont(data, img_filter);
|
||||
Font * font = instance->newFont(rasterizer, img_filter);
|
||||
|
||||
if(font == 0)
|
||||
return luaL_error(L, "Could not load font.");
|
||||
@@ -409,14 +413,18 @@ namespace opengl
|
||||
lua_gettable(L, -2);
|
||||
c.b = (unsigned char)luaL_checkint(L, -1);
|
||||
lua_pop(L, 1);
|
||||
lua_pushinteger(L, 4);
|
||||
lua_gettable(L, -2);
|
||||
c.a = (unsigned char)luaL_optint(L, -1, 255);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
c.r = (unsigned char)luaL_checkint(L, 1);
|
||||
c.g = (unsigned char)luaL_checkint(L, 2);
|
||||
c.b = (unsigned char)luaL_checkint(L, 3);
|
||||
c.a = (unsigned char)luaL_optint(L, 4, 255);
|
||||
}
|
||||
c.a = 255;
|
||||
instance->setBackgroundColor(c);
|
||||
return 0;
|
||||
}
|
||||
@@ -469,14 +477,10 @@ namespace opengl
|
||||
luax_convobj(L, idxs, 2, "font", "newRasterizer");
|
||||
}
|
||||
|
||||
// Convert to FontData, if necessary.
|
||||
if(luax_istype(L, 1, FONT_RASTERIZER_T))
|
||||
luax_convobj(L, 1, "font", "newFontData");
|
||||
|
||||
love::font::FontData * data = luax_checktype<love::font::FontData>(L, 1, "FontData", FONT_FONT_DATA_T);
|
||||
love::font::Rasterizer * rasterizer = luax_checktype<love::font::Rasterizer>(L, 1, "Rasterizer", FONT_RASTERIZER_T);
|
||||
|
||||
// Create the font.
|
||||
font = instance->newFont(data);
|
||||
font = instance->newFont(rasterizer);
|
||||
|
||||
if(font == 0)
|
||||
return luaL_error(L, "Could not load font.");
|
||||
@@ -579,20 +583,6 @@ namespace opengl
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_setLineStipple(lua_State * L)
|
||||
{
|
||||
if(lua_gettop(L) == 0)
|
||||
{
|
||||
instance->setLineStipple();
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned short pattern = (unsigned short)luaL_checkint(L, 1);
|
||||
int repeat = luaL_optint(L, 2, 1);
|
||||
instance->setLineStipple(pattern, repeat);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_getLineWidth(lua_State * L)
|
||||
{
|
||||
lua_pushnumber(L, instance->getLineWidth());
|
||||
@@ -608,11 +598,6 @@ namespace opengl
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_getLineStipple(lua_State * L)
|
||||
{
|
||||
return instance->getLineStipple(L);
|
||||
}
|
||||
|
||||
int w_setPointSize(lua_State * L)
|
||||
{
|
||||
float size = (float)luaL_checknumber(L, 1);
|
||||
@@ -799,15 +784,32 @@ namespace opengl
|
||||
int w_line(lua_State * L)
|
||||
{
|
||||
int args = lua_gettop(L);
|
||||
if( args == 1 || args > 4) {
|
||||
instance->polyline(L);
|
||||
} else {
|
||||
float x1 = (float)luaL_checknumber(L, 1);
|
||||
float y1 = (float)luaL_checknumber(L, 2);
|
||||
float x2 = (float)luaL_checknumber(L, 3);
|
||||
float y2 = (float)luaL_checknumber(L, 4);
|
||||
instance->line(x1, y1, x2, y2);
|
||||
bool is_table = false;
|
||||
if (args == 1 && lua_istable(L, 1)) {
|
||||
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");
|
||||
else if (args < 4)
|
||||
return luaL_error(L, "Need at least two vertices to draw a line");
|
||||
|
||||
float* coords = new float[args];
|
||||
if (is_table) {
|
||||
for (int i = 0; i < args; ++i) {
|
||||
lua_pushnumber(L, i + 1);
|
||||
lua_rawget(L, 1);
|
||||
coords[i] = lua_tonumber(L, -1);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < args; ++i)
|
||||
coords[i] = lua_tonumber(L, i + 1);
|
||||
}
|
||||
|
||||
instance->polyline(coords, args);
|
||||
|
||||
delete[] coords;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -876,10 +878,66 @@ namespace opengl
|
||||
instance->circle(mode, x, y, radius, points);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_arc(lua_State * L)
|
||||
{
|
||||
Graphics::DrawMode mode;
|
||||
const char * str = luaL_checkstring(L, 1);
|
||||
if(!Graphics::getConstant(str, mode))
|
||||
return luaL_error(L, "Incorrect draw mode %s", str);
|
||||
|
||||
float x = (float)luaL_checknumber(L, 2);
|
||||
float y = (float)luaL_checknumber(L, 3);
|
||||
float radius = (float)luaL_checknumber(L, 4);
|
||||
float angle1 = (float)luaL_checknumber(L, 5);
|
||||
float angle2 = (float)luaL_checknumber(L, 6);
|
||||
int points = luaL_optint(L, 7, 10);
|
||||
instance->arc(mode, x, y, radius, angle1, angle2, points);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_polygon(lua_State * L)
|
||||
{
|
||||
return instance->polygon(L);
|
||||
int args = lua_gettop(L) - 1;
|
||||
|
||||
Graphics::DrawMode mode;
|
||||
const char * str = luaL_checkstring(L, 1);
|
||||
if(!Graphics::getConstant(str, mode))
|
||||
return luaL_error(L, "Invalid draw mode: %s", str);
|
||||
|
||||
bool is_table = false;
|
||||
float* coords;
|
||||
if (args == 1 && lua_istable(L, 2)) {
|
||||
args = lua_objlen(L, 2);
|
||||
is_table = true;
|
||||
}
|
||||
|
||||
if (args % 2 != 0)
|
||||
return luaL_error(L, "Number of vertices must be a multiple of two");
|
||||
else if (args < 6)
|
||||
return luaL_error(L, "Need at least three vertices to draw a polygon");
|
||||
|
||||
// fetch coords
|
||||
coords = new float[args + 2];
|
||||
if (is_table) {
|
||||
for (int i = 0; i < args; ++i) {
|
||||
lua_pushnumber(L, i + 1);
|
||||
lua_rawget(L, 2);
|
||||
coords[i] = lua_tonumber(L, -1);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < args; ++i)
|
||||
coords[i] = lua_tonumber(L, i + 2);
|
||||
}
|
||||
|
||||
// make a closed loop
|
||||
coords[args] = coords[0];
|
||||
coords[args+1] = coords[1];
|
||||
instance->polygon(mode, coords, args+2);
|
||||
delete[] coords;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_push(lua_State *)
|
||||
@@ -934,7 +992,6 @@ namespace opengl
|
||||
{ "present", w_present },
|
||||
|
||||
{ "newImage", w_newImage },
|
||||
{ "newGlyph", w_newGlyph },
|
||||
{ "newQuad", w_newQuad },
|
||||
{ "newFont1", w_newFont1 },
|
||||
{ "newImageFont", w_newImageFont },
|
||||
@@ -957,10 +1014,8 @@ namespace opengl
|
||||
{ "setLineWidth", w_setLineWidth },
|
||||
{ "setLineStyle", w_setLineStyle },
|
||||
{ "setLine", w_setLine },
|
||||
{ "setLineStipple", w_setLineStipple },
|
||||
{ "getLineWidth", w_getLineWidth },
|
||||
{ "getLineStyle", w_getLineStyle },
|
||||
{ "getLineStipple", w_getLineStipple },
|
||||
{ "setPointSize", w_setPointSize },
|
||||
{ "setPointStyle", w_setPointStyle },
|
||||
{ "setPoint", w_setPoint },
|
||||
@@ -992,12 +1047,16 @@ namespace opengl
|
||||
{ "setScissor", w_setScissor },
|
||||
{ "getScissor", w_getScissor },
|
||||
|
||||
{ "defineMask", w_defineMask },
|
||||
{ "setMask", w_setMask },
|
||||
|
||||
{ "point", w_point },
|
||||
{ "line", w_line },
|
||||
{ "triangle", w_triangle },
|
||||
{ "rectangle", w_rectangle },
|
||||
{ "quad", w_quad },
|
||||
{ "circle", w_circle },
|
||||
{ "arc", w_arc },
|
||||
|
||||
{ "polygon", w_polygon },
|
||||
|
||||
@@ -1017,7 +1076,6 @@ namespace opengl
|
||||
static const lua_CFunction types[] = {
|
||||
luaopen_font,
|
||||
luaopen_image,
|
||||
luaopen_glyph,
|
||||
luaopen_frame,
|
||||
luaopen_spritebatch,
|
||||
luaopen_particlesystem,
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
// LOVE
|
||||
#include "wrap_Font.h"
|
||||
#include "wrap_Image.h"
|
||||
#include "wrap_Glyph.h"
|
||||
#include "wrap_Quad.h"
|
||||
#include "wrap_SpriteBatch.h"
|
||||
#include "wrap_ParticleSystem.h"
|
||||
@@ -51,8 +50,9 @@ namespace opengl
|
||||
int w_isCreated(lua_State * L);
|
||||
int w_setScissor(lua_State * L);
|
||||
int w_getScissor(lua_State * L);
|
||||
int w_defineMask(lua_State * L);
|
||||
int w_setMask(lua_State * L);
|
||||
int w_newImage(lua_State * L);
|
||||
int w_newGlyph(lua_State * L);
|
||||
int w_newQuad(lua_State * L);
|
||||
int w_newFrame(lua_State * L);
|
||||
int w_newFont1(lua_State * L);
|
||||
@@ -96,6 +96,7 @@ namespace opengl
|
||||
int w_rectangle(lua_State * L);
|
||||
int w_quad(lua_State * L);
|
||||
int w_circle(lua_State * L);
|
||||
int w_arc(lua_State * L);
|
||||
int w_push(lua_State * L);
|
||||
int w_pop(lua_State * L);
|
||||
int w_rotate(lua_State * L);
|
||||
|
||||
@@ -143,13 +143,19 @@ namespace opengl
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_ParticleSystem_setSize(lua_State * L)
|
||||
int w_ParticleSystem_setSizes(lua_State * L)
|
||||
{
|
||||
ParticleSystem * t = luax_checkparticlesystem(L, 1);
|
||||
float arg1 = (float)luaL_checknumber(L, 2);
|
||||
float arg2 = (float)luaL_optnumber(L, 3, arg1);
|
||||
float arg3 = (float)luaL_optnumber(L, 4, 0);
|
||||
t->setSize(arg1, arg2, arg3);
|
||||
size_t nSizes = lua_gettop(L) - 1;
|
||||
if (nSizes == 1) {
|
||||
t->setSize(luaL_checknumber(L, 2));
|
||||
} else {
|
||||
std::vector<float> sizes(nSizes);
|
||||
for (size_t i = 0; i < nSizes; ++i)
|
||||
sizes[i] = luaL_checknumber(L, 1 + i + 1);
|
||||
|
||||
t->setSize(sizes);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -188,28 +194,26 @@ namespace opengl
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_ParticleSystem_setColor(lua_State * L)
|
||||
int w_ParticleSystem_setColors(lua_State * L)
|
||||
{
|
||||
ParticleSystem * t = luax_checkparticlesystem(L, 1);
|
||||
|
||||
unsigned char start[4];
|
||||
size_t nColors = (lua_gettop(L) - 1) / 4;
|
||||
|
||||
start[0] = (unsigned char)luaL_checkint(L, 2);
|
||||
start[1] = (unsigned char)luaL_checkint(L, 3);
|
||||
start[2] = (unsigned char)luaL_checkint(L, 4);
|
||||
start[3] = (unsigned char)luaL_checkint(L, 5);
|
||||
|
||||
if(lua_gettop(L) > 5)
|
||||
{
|
||||
unsigned char end[4];
|
||||
end[0] = (unsigned char)luaL_checkint(L, 6);
|
||||
end[1] = (unsigned char)luaL_checkint(L, 7);
|
||||
end[2] = (unsigned char)luaL_checkint(L, 8);
|
||||
end[3] = (unsigned char)luaL_checkint(L, 9);
|
||||
t->setColor(start, end);
|
||||
if (nColors == 1) {
|
||||
t->setColor(Color(luaL_checkint(L,2),
|
||||
luaL_checkint(L,3),
|
||||
luaL_checkint(L,4),
|
||||
luaL_checkint(L,5)));
|
||||
} else {
|
||||
std::vector<Color> colors(nColors);
|
||||
for (size_t i = 0; i < nColors; ++i) {
|
||||
colors[i] = Color(luaL_checkint(L, 1 + i*4 + 1),
|
||||
luaL_checkint(L, 1 + i*4 + 2),
|
||||
luaL_checkint(L, 1 + i*4 + 3),
|
||||
luaL_checkint(L, 1 + i*4 + 4));
|
||||
}
|
||||
t->setColor(colors);
|
||||
}
|
||||
else
|
||||
t->setColor(start);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -343,12 +347,12 @@ namespace opengl
|
||||
{ "setGravity", w_ParticleSystem_setGravity },
|
||||
{ "setRadialAcceleration", w_ParticleSystem_setRadialAcceleration },
|
||||
{ "setTangentialAcceleration", w_ParticleSystem_setTangentialAcceleration },
|
||||
{ "setSize", w_ParticleSystem_setSize },
|
||||
{ "setSizes", w_ParticleSystem_setSizes },
|
||||
{ "setSizeVariation", w_ParticleSystem_setSizeVariation },
|
||||
{ "setRotation", w_ParticleSystem_setRotation },
|
||||
{ "setSpin", w_ParticleSystem_setSpin },
|
||||
{ "setSpinVariation", w_ParticleSystem_setSpinVariation },
|
||||
{ "setColor", w_ParticleSystem_setColor },
|
||||
{ "setColors", w_ParticleSystem_setColors },
|
||||
{ "setOffset", w_ParticleSystem_setOffset },
|
||||
{ "getX", w_ParticleSystem_getX },
|
||||
{ "getY", w_ParticleSystem_getY },
|
||||
|
||||
@@ -46,12 +46,12 @@ namespace opengl
|
||||
int w_ParticleSystem_setGravity(lua_State * L);
|
||||
int w_ParticleSystem_setRadialAcceleration(lua_State * L);
|
||||
int w_ParticleSystem_setTangentialAcceleration(lua_State * L);
|
||||
int w_ParticleSystem_setSize(lua_State * L);
|
||||
int w_ParticleSystem_setSizes(lua_State * L);
|
||||
int w_ParticleSystem_setSizeVariation(lua_State * L);
|
||||
int w_ParticleSystem_setRotation(lua_State * L);
|
||||
int w_ParticleSystem_setSpin(lua_State * L);
|
||||
int w_ParticleSystem_setSpinVariation(lua_State * L);
|
||||
int w_ParticleSystem_setColor(lua_State * L);
|
||||
int w_ParticleSystem_setColors(lua_State * L);
|
||||
int w_ParticleSystem_setOffset(lua_State * L);
|
||||
int w_ParticleSystem_getX(lua_State * L);
|
||||
int w_ParticleSystem_getY(lua_State * L);
|
||||
|
||||
Reference in New Issue
Block a user