mirror of
https://github.com/love2d/love.git
synced 2026-08-15 15:51:12 +02:00
Replace line drawing via GL_LINE with custom line drawing (issue #153)
Allows for correctly scaleable lines, (very) big line widths. Corners in rectangles/triangles/... join up nicely (issue #197). --HG-- branch : minor
This commit is contained in:
@@ -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;
|
||||
|
||||
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)
|
||||
@@ -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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
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)
|
||||
{
|
||||
float angle = angle2 - angle1;
|
||||
if (angle == 0) return;
|
||||
while (angle < 0) angle += LOVE_M_PI * 2;
|
||||
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;
|
||||
|
||||
|
||||
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;
|
||||
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); // 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)
|
||||
|
||||
@@ -76,11 +76,7 @@ namespace opengl
|
||||
Graphics::ColorMode colorMode;
|
||||
|
||||
// Line.
|
||||
float lineWidth;
|
||||
Graphics::LineStyle lineStyle;
|
||||
bool stipple;
|
||||
GLint stippleRepeat;
|
||||
GLint stipplePattern;
|
||||
|
||||
// Point.
|
||||
float pointSize;
|
||||
@@ -107,9 +103,7 @@ namespace opengl
|
||||
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;
|
||||
@@ -126,6 +120,8 @@ namespace opengl
|
||||
Font * currentFont;
|
||||
DisplayMode currentMode;
|
||||
|
||||
float lineWidth;
|
||||
|
||||
public:
|
||||
|
||||
Graphics();
|
||||
@@ -335,16 +331,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.
|
||||
**/
|
||||
@@ -355,13 +341,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.
|
||||
**/
|
||||
@@ -423,20 +402,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.
|
||||
@@ -488,9 +460,10 @@ namespace opengl
|
||||
/**
|
||||
* 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.
|
||||
|
||||
@@ -556,20 +556,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());
|
||||
@@ -585,11 +571,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);
|
||||
@@ -776,15 +757,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;
|
||||
}
|
||||
|
||||
@@ -873,7 +871,46 @@ namespace opengl
|
||||
|
||||
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 + 1);
|
||||
}
|
||||
|
||||
// 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 *)
|
||||
@@ -950,10 +987,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 },
|
||||
|
||||
Reference in New Issue
Block a user