ultimatepp/uppsrc/GLDraw/Tellipse.cpp
cxl 0e98f17dd8 GLDraw: Fixed issue with DrawEllipse
git-svn-id: svn://ultimatepp.org/upp/trunk@12653 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2019-01-08 11:18:09 +00:00

76 lines
No EOL
1.7 KiB
C++

#include "GLDraw.h"
namespace Upp {
void Ellipse(GLTriangles& tr, Pointf center, Sizef radius, Color color,
double width, Color line_color, double alpha)
{
static Pointf e[256];
static byte step[65];
ONCELOCK {
for(int i = 0; i < 256; i++)
e[i] = Polar(i * M_2PI / 256.0);
for(int i = 0; i < 65; i++) {
int h = 2 * i;
int s = 4;
while(s < h)
s += s;
step[i] = 256 / min(s, 256);
}
}
double rmin = min(radius.cx, radius.cy);
if(rmin <= 1e-100)
return;
int st = (int)max(radius.cx, radius.cy);
st = st < 65 ? step[st] : 1;
if(width >= rmin) {
width = 0;
color = line_color;
}
bool circle = radius.cx == radius.cy;
if(width >= 0 && circle)
width = width / radius.cx;
int c = tr.Vertex(center, color, alpha);
int a, a0;
int la, lao, la0, lao0;
bool has_line = width > 0 && !IsNull(line_color);
bool has_interior = !IsNull(color);
for(int i = 0; i < 256; i += st) {
Pointf dir = radius * e[i];
int b, lb, lbo;
if(has_line) { // we need to draw border line
lbo = tr.Vertex(center + dir, line_color, alpha); // outer point
dir -= circle ? width * dir : width * Normalize(dir);
lb = tr.Vertex(center + dir, line_color, alpha); // inner point
}
b = tr.Vertex(center + dir, color, alpha);
if(i) {
if(has_line) {
tr.Triangle(la, lao, lbo);
tr.Triangle(lbo, lb, la);
}
if(has_interior)
tr.Triangle(c, a, b);
}
else {
a0 = b;
la0 = lb;
lao0 = lbo;
}
a = b;
la = lb;
lao = lbo;
}
if(has_interior)
tr.Triangle(c, a, a0);
if(has_line) {
tr.Triangle(la, lao, lao0);
tr.Triangle(lao0, la0, la);
}
}
};