|
@@ -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.
|
|
@@ -100,19 +101,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 +126,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]);
|
|
@@ -260,8 +246,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);
|
|
|
|
|
@@ -608,45 +593,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()
|
|
@@ -658,25 +628,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);
|
|
@@ -805,149 +762,90 @@ 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;
|
|
|
+
|
|
|
+ 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]);
|
|
|
|
|
|
- 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);
|
|
|
+ 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)
|
|
@@ -955,144 +853,77 @@ namespace opengl
|
|
|
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);
|
|
|
+ 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);
|
|
|
+ }
|
|
|
|
|
|
- for(float i = 0; i < two_pi; i+= angle_shift)
|
|
|
- glVertex2f(radius * sin(i),radius * cos(i));
|
|
|
+ coords[2*points] = coords[0];
|
|
|
+ coords[2*points+1] = coords[1];
|
|
|
|
|
|
- glEnd();
|
|
|
- break;
|
|
|
- }
|
|
|
+ polygon(mode, coords, (points + 1) * 2);
|
|
|
|
|
|
- glPopMatrix();
|
|
|
- glEnable(GL_TEXTURE_2D);
|
|
|
+ delete[] coords;
|
|
|
}
|
|
|
|
|
|
void Graphics::arc(DrawMode mode, float x, float y, float radius, float angle1, float angle2, int points)
|
|
|
{
|
|
|
- float angle = angle2 - angle1;
|
|
|
- if (angle == 0) return;
|
|
|
- while (angle < 0) angle += LOVE_M_PI * 2;
|
|
|
- if(points <= 0) points = 1;
|
|
|
- float angle_shift = (angle / points);
|
|
|
-
|
|
|
- glDisable(GL_TEXTURE_2D);
|
|
|
- glPushMatrix();
|
|
|
-
|
|
|
- glTranslatef(x, y, 0.0f);
|
|
|
-
|
|
|
- switch(mode)
|
|
|
- {
|
|
|
- case DRAW_LINE:
|
|
|
- glBegin(GL_LINE_LOOP);
|
|
|
-
|
|
|
- glVertex2f(0, 0);
|
|
|
-
|
|
|
- for(float i = 0; i <= angle+angle_shift/2; i+= angle_shift)
|
|
|
- glVertex2f(radius * cos(i+angle1),radius * sin(i+angle1));
|
|
|
-
|
|
|
- glEnd();
|
|
|
- break;
|
|
|
-
|
|
|
- default:
|
|
|
- case DRAW_FILL:
|
|
|
- glBegin(GL_TRIANGLE_FAN);
|
|
|
-
|
|
|
- glVertex2f(0, 0);
|
|
|
-
|
|
|
- for(float i = 0; i <= angle+angle_shift/2; i+= angle_shift)
|
|
|
- glVertex2f(radius * cos(i+angle1),radius * sin(i+angle1));
|
|
|
-
|
|
|
- glEnd();
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- glPopMatrix();
|
|
|
- glEnable(GL_TEXTURE_2D);
|
|
|
- }
|
|
|
-
|
|
|
- int Graphics::polygon( lua_State * L )
|
|
|
- {
|
|
|
- // 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;
|
|
|
+ angle1 = fmod(angle1, 2 * LOVE_M_PI);
|
|
|
+ angle2 = fmod(angle2, 2 * LOVE_M_PI);
|
|
|
+ if (angle1 == angle2)
|
|
|
+ return;
|
|
|
+ else if (angle1 > angle2)
|
|
|
+ angle2 += LOVE_M_PI * 2;
|
|
|
|
|
|
- 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);
|
|
|
+ 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
|
|
|
|
|
|
- // 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.");
|
|
|
+ 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);
|
|
|
}
|
|
|
|
|
|
+ }
|
|
|
|
|
|
- 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;
|
|
|
+ /// @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)
|
|
|
+ {
|
|
|
+ // 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); // opengl will close the polygon for us
|
|
|
+ glDisableClientState(GL_VERTEX_ARRAY);
|
|
|
+ glEnable(GL_TEXTURE_2D);
|
|
|
}
|
|
|
-
|
|
|
- glEnd();
|
|
|
-
|
|
|
- glEnable(GL_TEXTURE_2D);
|
|
|
-
|
|
|
- return 0;
|
|
|
}
|
|
|
|
|
|
love::image::ImageData * Graphics::newScreenshot(love::image::Image * image)
|