mirror of https://github.com/buggins/dlangui.git
line, polyLine with width - implementation for OpenGL
This commit is contained in:
parent
f7d84b1403
commit
e715c52d0b
|
@ -189,9 +189,31 @@ enum : int {
|
|||
ACTION_FILE_EXIT,
|
||||
}
|
||||
|
||||
debug(SDLSettings) {
|
||||
import dlangui.core.settings;
|
||||
void testSDL(string fn) {
|
||||
Log.d("Loading SDL from ", fn);
|
||||
Setting s = new Setting();
|
||||
if (s.load(fn)) {
|
||||
Log.d("JSON:\n", s.toJSON(true));
|
||||
} else {
|
||||
Log.e("failed to read SDL from ", fn);
|
||||
}
|
||||
}
|
||||
void testSDLSettings() {
|
||||
testSDL(`C:\Users\vlopatin\AppData\Roaming\.dlangide\settings.json`);
|
||||
testSDL("dub.json");
|
||||
testSDL("test1.sdl");
|
||||
}
|
||||
}
|
||||
|
||||
/// entry point for dlangui based application
|
||||
extern (C) int UIAppMain(string[] args) {
|
||||
|
||||
debug(SDLSettings) {
|
||||
testSDLSettings();
|
||||
}
|
||||
|
||||
// always use trace, even for release builds
|
||||
//Log.setLogLevel(LogLevel.Trace);
|
||||
//Log.setFileLogger(new std.stdio.File("ui.log", "w"));
|
||||
|
@ -1069,6 +1091,8 @@ void main()
|
|||
canvas.font.drawText(buf, x + 200, y + 250, "drawLine()"d, 0x800020);
|
||||
for (int i = 0; i < 40; i+=3)
|
||||
buf.drawLine(Point(x+200 + i * 4, y+290), Point(x+150 + i * 7, y+420 + i * 2), 0x008000 + i * 5);
|
||||
PointF[] poly = [vec2(130, 150), vec2(240, 110), vec2(270, 170), vec2(300, 290), vec2(220, 400), vec2(180, 330)];
|
||||
buf.polyLineF(poly, 3.5f, 0x804020, true);
|
||||
};
|
||||
tabs.addTab(canvas, "TAB_CANVAS"c);
|
||||
|
||||
|
|
|
@ -189,7 +189,7 @@ struct vec2 {
|
|||
return res;
|
||||
}
|
||||
/// subtract value from all components of vector
|
||||
vec3 opBinary(string op : "-")(const vec2 v) const {
|
||||
vec2 opBinary(string op : "-")(const vec2 v) const {
|
||||
vec2 res = this;
|
||||
res.vec[0] -= v.vec[0];
|
||||
res.vec[1] -= v.vec[1];
|
||||
|
@ -1723,3 +1723,6 @@ vec3 triangleNormal(vec3 p1, vec3 p2, vec3 p3) {
|
|||
vec3 triangleNormal(float[3] p1, float[3] p2, float[3] p3) {
|
||||
return vec3.crossProduct(vec3(p2) - vec3(p1), vec3(p3) - vec3(p2)).normalized();
|
||||
}
|
||||
|
||||
/// Alias for 2d float point
|
||||
alias PointF = vec2;
|
||||
|
|
|
@ -19,6 +19,7 @@ module dlangui.graphics.drawbuf;
|
|||
|
||||
public import dlangui.core.config;
|
||||
public import dlangui.core.types;
|
||||
public import dlangui.core.math3d;
|
||||
import dlangui.core.logger;
|
||||
import dlangui.graphics.colors;
|
||||
|
||||
|
@ -370,6 +371,54 @@ class DrawBuf : RefCountedObject {
|
|||
}
|
||||
}
|
||||
|
||||
/// draw filled triangle in float coordinates
|
||||
void fillTriangleF(PointF p1, PointF p2, PointF p3, uint colour) {
|
||||
// override and implement it
|
||||
}
|
||||
|
||||
/// draw filled quad in float coordinates
|
||||
void fillQuadF(PointF p1, PointF p2, PointF p3, PointF p4, uint colour) {
|
||||
fillTriangleF(p1, p2, p3, colour);
|
||||
fillTriangleF(p3, p4, p1, colour);
|
||||
}
|
||||
|
||||
/// draw line of arbitrary width in float coordinates
|
||||
void drawLineF(PointF p1, PointF p2, float width, uint colour) {
|
||||
// direction vector
|
||||
PointF v = (p2 - p1).normalized;
|
||||
// calculate normal vector
|
||||
PointF n;
|
||||
// rotate CCW 90 degrees
|
||||
n.y = v.x;
|
||||
n.x = -v.y;
|
||||
// offset by normal * half_width
|
||||
n *= width / 2;
|
||||
// draw line using quad
|
||||
fillQuadF(p1 - n, p2 - n, p2 + n, p1 + n, colour);
|
||||
}
|
||||
|
||||
/// draw poly line of arbitrary width in float coordinates; when cycled is true, connect first and last point
|
||||
void polyLineF(PointF[] points, float width, uint colour, bool cycled) {
|
||||
if (points.length < 2)
|
||||
return;
|
||||
for(int i = 0; i + 1 < points.length; i++) {
|
||||
drawLineF(points[i], points[i + 1], width, colour);
|
||||
}
|
||||
if (cycled && points.length > 2)
|
||||
drawLineF(points[$ - 1], points[0], width, colour);
|
||||
}
|
||||
|
||||
/// draw poly line of width == 1px; when cycled is true, connect first and last point
|
||||
void polyLine(Point[] points, uint colour, bool cycled) {
|
||||
if (points.length < 2)
|
||||
return;
|
||||
for(int i = 0; i + 1 < points.length; i++) {
|
||||
drawLine(points[i], points[i + 1], colour);
|
||||
}
|
||||
if (cycled && points.length > 2)
|
||||
drawLine(points[$ - 1], points[0], colour);
|
||||
}
|
||||
|
||||
/// draw line from point p1 to p2 with specified color
|
||||
void drawLine(Point p1, Point p2, uint colour) {
|
||||
if (!clipLine(_clipRect, p1, p2))
|
||||
|
|
|
@ -180,6 +180,16 @@ class GLDrawBuf : DrawBuf, GLConfigCallback {
|
|||
_scene.add(new LineSceneItem(p1, p2, colour));
|
||||
}
|
||||
|
||||
/// draw filled triangle in float coordinates
|
||||
override void fillTriangleF(PointF p1, PointF p2, PointF p3, uint colour) {
|
||||
assert(_scene !is null);
|
||||
//if (!clipLine(_clipRect, p1, p2))
|
||||
// return;
|
||||
// TODO: clipping
|
||||
_scene.add(new TriangleSceneItem(p1, p2, p3, colour));
|
||||
}
|
||||
|
||||
|
||||
/// cleanup resources
|
||||
override void clear() {
|
||||
if (_framebuffer) {
|
||||
|
@ -722,6 +732,25 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
private class TriangleSceneItem : SceneItem {
|
||||
private:
|
||||
PointF _p1;
|
||||
PointF _p2;
|
||||
PointF _p3;
|
||||
uint _color;
|
||||
|
||||
public:
|
||||
this(PointF p1, PointF p2, PointF p3, uint color) {
|
||||
_p1 = p1;
|
||||
_p2 = p2;
|
||||
_p3 = p3;
|
||||
_color = color;
|
||||
}
|
||||
override void draw() {
|
||||
glSupport.batch.addTriangle(_p1, _p2, _p3, _color, _color, _color);
|
||||
}
|
||||
}
|
||||
|
||||
private class SolidRectSceneItem : SceneItem {
|
||||
private:
|
||||
Rect _rc;
|
||||
|
|
|
@ -26,6 +26,7 @@ public import dlangui.core.math3d;
|
|||
|
||||
import dlangui.core.logger;
|
||||
import dlangui.core.types;
|
||||
import dlangui.core.math3d;
|
||||
|
||||
import std.conv;
|
||||
import std.string;
|
||||
|
@ -965,6 +966,18 @@ final class GLSupport {
|
|||
return indexes;
|
||||
}
|
||||
|
||||
/// make indexes for rectangle TRIANGLES (2 triangles == 6 vertexes per rect)
|
||||
protected int[] makeTriangleIndexesArray(size_t pointCount) {
|
||||
int[] indexes;
|
||||
indexes.assumeSafeAppend();
|
||||
for (uint i = 0; i + 2 < pointCount; i += 3) {
|
||||
indexes ~= i + 0;
|
||||
indexes ~= i + 1;
|
||||
indexes ~= i + 2;
|
||||
}
|
||||
return indexes;
|
||||
}
|
||||
|
||||
/// make indexes for LINES
|
||||
protected int[] makeLineIndexesArray(size_t lineCount) {
|
||||
int[] indexes;
|
||||
|
@ -1035,6 +1048,58 @@ final class GLSupport {
|
|||
}
|
||||
}
|
||||
|
||||
void drawSolidFillTriangles(PointF[] points, uint[] vertexColors) {
|
||||
//Log.v("drawSolidFillRects rects:", rects.length, " colors:", vertexColors.length);
|
||||
float[] colors = convertColors(vertexColors);
|
||||
|
||||
float[] vertexArray;
|
||||
vertexArray.assumeSafeAppend();
|
||||
|
||||
for (uint i = 0; i + 2 < points.length; i += 3) {
|
||||
float x0 = points[i+0].x;
|
||||
float y0 = currentFBO ? points[i+0].y : (bufferDy - points[i+0].y);
|
||||
float x1 = points[i+1].x;
|
||||
float y1 = currentFBO ? points[i+1].y : (bufferDy - points[i+1].y);
|
||||
float x2 = points[i+2].x;
|
||||
float y2 = currentFBO ? points[i+2].y : (bufferDy - points[i+2].y);
|
||||
|
||||
float[3 * 3] vertices = [
|
||||
x0,y0,Z_2D,
|
||||
x1,y1,Z_2D,
|
||||
x2,y2,Z_2D];
|
||||
|
||||
vertexArray ~= vertices;
|
||||
}
|
||||
|
||||
int[] indexes = makeTriangleIndexesArray(points.length);
|
||||
|
||||
if (_legacyMode) {
|
||||
static if (SUPPORT_LEGACY_OPENGL) {
|
||||
glColor4f(1,1,1,1);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glEnable(GL_BLEND);
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
checkgl!glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
checkgl!glEnableClientState(GL_VERTEX_ARRAY);
|
||||
checkgl!glEnableClientState(GL_COLOR_ARRAY);
|
||||
checkgl!glVertexPointer(3, GL_FLOAT, 0, cast(void*)vertexArray.ptr);
|
||||
checkgl!glColorPointer(4, GL_FLOAT, 0, cast(void*)colors.ptr);
|
||||
|
||||
checkgl!glDrawElements(GL_TRIANGLES, cast(int)indexes.length, GL_UNSIGNED_INT, cast(void*)indexes.ptr);
|
||||
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
} else {
|
||||
if (_solidFillProgram !is null) {
|
||||
_solidFillProgram.execute(vertexArray, colors, indexes);
|
||||
} else
|
||||
Log.e("No program");
|
||||
}
|
||||
}
|
||||
|
||||
float[] convertColors(uint[] cols) {
|
||||
float[] colors;
|
||||
colors.assumeSafeAppend();
|
||||
|
@ -1691,6 +1756,12 @@ class OpenGLBatch {
|
|||
_colors ~= color4;
|
||||
}
|
||||
|
||||
void addTriangle(PointF p1, PointF p2, PointF p3, uint color1, uint color2, uint color3) {
|
||||
flush();
|
||||
// TODO: batch triangles
|
||||
glSupport.drawSolidFillTriangles([p1, p2, p3], [color1, color2, color3]);
|
||||
}
|
||||
|
||||
/// add gradient rect
|
||||
void addLine(Rect dstRect, uint color1, uint color2) {
|
||||
flush();
|
||||
|
|
Loading…
Reference in New Issue