mirror of
https://github.com/Ttanasart-pt/Pixel-Composer.git
synced 2024-12-24 14:06:23 +01:00
- [Canvas] Fix flood fill, magic selector combine black and fully transparent pixels.
This commit is contained in:
parent
1274fc9405
commit
196daeb849
8 changed files with 177 additions and 109 deletions
|
@ -77,7 +77,7 @@ event_inherited();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(preset_selecting == i)
|
if(preset_selecting == i)
|
||||||
var _palRes = drawPaletteGrid(pal.palette, ui(16), yy + ui(28), ww, _gs, selector.current_color);
|
var _palRes = drawPaletteGrid(pal.palette, ui(16), yy + ui(28), ww, _gs, { color : selector.current_color, mx : _m[0], my : _m[1] });
|
||||||
else
|
else
|
||||||
drawPalette(pal.palette, ui(16), yy + ui(28), ww, ui(20));
|
drawPalette(pal.palette, ui(16), yy + ui(28), ww, ui(20));
|
||||||
|
|
||||||
|
|
|
@ -190,7 +190,7 @@ event_inherited();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(palette_selecting == i)
|
if(palette_selecting == i)
|
||||||
var _palRes = drawPaletteGrid(pal.palette, ui(16), yy + ui(28), ww, _gs);
|
var _palRes = drawPaletteGrid(pal.palette, ui(16), yy + ui(28), ww, _gs, { mx : _m[0], my : _m[1] });
|
||||||
else
|
else
|
||||||
drawPalette(pal.palette, ui(16), yy + ui(28), ww, ui(20));
|
drawPalette(pal.palette, ui(16), yy + ui(28), ww, ui(20));
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,15 @@ function _ff_getPixel(_x, _y) { return buffer_read_at(_ff_buff, (_y * _ff_w + _x
|
||||||
|
|
||||||
function canvas_ff_fillable(colorBase, colorFill, _x, _y, _thres) { #region
|
function canvas_ff_fillable(colorBase, colorFill, _x, _y, _thres) { #region
|
||||||
var c = _ff_getPixel(_x, _y);
|
var c = _ff_getPixel(_x, _y);
|
||||||
var d = color_diff(colorBase, c, true, true);
|
var d = color_diff_alpha(colorBase, c);
|
||||||
|
//print($"Checking [{_x}, {_y}]: {colorBase} - {c} : {_color_get_alpha(colorBase)} - {_color_get_alpha(c)} | {d}");
|
||||||
return d <= _thres && c != colorFill;
|
return d <= _thres && c != colorFill;
|
||||||
} #endregion
|
} #endregion
|
||||||
|
|
||||||
function canvas_flood_fill_scanline(_surf, _x, _y, _thres, _corner = false) { #region
|
function canvas_flood_fill_scanline(_surf, _x, _y, _thres, _corner = false) { #region
|
||||||
|
|
||||||
var colorFill = CURRENT_COLOR;
|
var colorFill = CURRENT_COLOR;
|
||||||
var colorBase = surface_getpixel_ext(_surf, _x, _y);
|
var colorBase = int64(surface_getpixel_ext(_surf, _x, _y));
|
||||||
|
|
||||||
if(colorFill == colorBase) return; //Clicking on the same color as the fill color
|
if(colorFill == colorBase) return; //Clicking on the same color as the fill color
|
||||||
|
|
||||||
|
@ -24,13 +26,15 @@ function canvas_flood_fill_scanline(_surf, _x, _y, _thres, _corner = false) { #r
|
||||||
var spanAbove, spanBelow;
|
var spanAbove, spanBelow;
|
||||||
var thr = _thres * _thres;
|
var thr = _thres * _thres;
|
||||||
|
|
||||||
var queue = ds_queue_create();
|
var qx = ds_queue_create();
|
||||||
ds_queue_enqueue(queue, [_x, _y]);
|
var qy = ds_queue_create();
|
||||||
|
ds_queue_enqueue(qx, _x);
|
||||||
|
ds_queue_enqueue(qy, _y);
|
||||||
|
|
||||||
while(!ds_queue_empty(queue)) {
|
while(!ds_queue_empty(qx)) {
|
||||||
var pos = ds_queue_dequeue(queue);
|
|
||||||
x1 = pos[0];
|
x1 = ds_queue_dequeue(qx);
|
||||||
y1 = pos[1];
|
y1 = ds_queue_dequeue(qy);
|
||||||
|
|
||||||
if(_ff_getPixel(x1, y1) == colorFill) continue; //Color in queue is already filled
|
if(_ff_getPixel(x1, y1) == colorFill) continue; //Color in queue is already filled
|
||||||
|
|
||||||
|
@ -47,32 +51,47 @@ function canvas_flood_fill_scanline(_surf, _x, _y, _thres, _corner = false) { #r
|
||||||
buffer_write(_ff_buff, buffer_u32, _c);
|
buffer_write(_ff_buff, buffer_u32, _c);
|
||||||
|
|
||||||
if(y1 > 0) {
|
if(y1 > 0) {
|
||||||
if(_corner && x1 > 0 && canvas_ff_fillable(colorBase, colorFill, x1 - 1, y1 - 1, thr)) //Check top left pixel
|
if(_corner && x1 > 0 && canvas_ff_fillable(colorBase, colorFill, x1 - 1, y1 - 1, thr)) { //Check top left pixel
|
||||||
ds_queue_enqueue(queue, [x1 - 1, y1 - 1]);
|
ds_queue_enqueue(qx, x1 - 1);
|
||||||
|
ds_queue_enqueue(qy, y1 - 1);
|
||||||
|
}
|
||||||
|
|
||||||
if(canvas_ff_fillable(colorBase, colorFill, x1, y1 - 1, thr)) //Check top pixel
|
if(canvas_ff_fillable(colorBase, colorFill, x1, y1 - 1, thr)) { //Check top pixel
|
||||||
ds_queue_enqueue(queue, [x1, y1 - 1]);
|
ds_queue_enqueue(qx, x1);
|
||||||
|
ds_queue_enqueue(qy, y1 - 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(y1 < surface_h - 1) {
|
if(y1 < surface_h - 1) {
|
||||||
if(_corner && x1 > 0 && canvas_ff_fillable(colorBase, colorFill, x1 - 1, y1 + 1, thr)) //Check bottom left pixel
|
if(_corner && x1 > 0 && canvas_ff_fillable(colorBase, colorFill, x1 - 1, y1 + 1, thr)) { //Check bottom left pixel
|
||||||
ds_queue_enqueue(queue, [x1 - 1, y1 + 1]);
|
ds_queue_enqueue(qx, x1 - 1);
|
||||||
|
ds_queue_enqueue(qy, y1 + 1);
|
||||||
|
}
|
||||||
|
|
||||||
if(canvas_ff_fillable(colorBase, colorFill, x1, y1 + 1, thr)) //Check bottom pixel
|
if(canvas_ff_fillable(colorBase, colorFill, x1, y1 + 1, thr)) { //Check bottom pixel
|
||||||
ds_queue_enqueue(queue, [x1, y1 + 1]);
|
ds_queue_enqueue(qx, x1);
|
||||||
|
ds_queue_enqueue(qy, y1 + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_corner && x1 < surface_w - 1) {
|
if(_corner && x1 < surface_w - 1) {
|
||||||
if(y1 > 0 && canvas_ff_fillable(colorBase, colorFill, x1 + 1, y1 - 1, thr)) //Check top right pixel
|
if(y1 > 0 && canvas_ff_fillable(colorBase, colorFill, x1 + 1, y1 - 1, thr)) { //Check top right pixel
|
||||||
ds_queue_enqueue(queue, [x1 + 1, y1 - 1]);
|
ds_queue_enqueue(qx, x1 + 1);
|
||||||
|
ds_queue_enqueue(qy, y1 - 1);
|
||||||
|
}
|
||||||
|
|
||||||
if(y1 < surface_h - 1 && canvas_ff_fillable(colorBase, colorFill, x1 + 1, y1 + 1, thr)) //Check bottom right pixel
|
if(y1 < surface_h - 1 && canvas_ff_fillable(colorBase, colorFill, x1 + 1, y1 + 1, thr)) { //Check bottom right pixel
|
||||||
ds_queue_enqueue(queue, [x1 + 1, y1 + 1]);
|
ds_queue_enqueue(qx, x1 + 1);
|
||||||
|
ds_queue_enqueue(qy, y1 + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
x1++;
|
x1++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ds_queue_destroy(qx);
|
||||||
|
ds_queue_destroy(qy);
|
||||||
|
|
||||||
draw_set_alpha(1);
|
draw_set_alpha(1);
|
||||||
buffer_delete(_ff_buff);
|
buffer_delete(_ff_buff);
|
||||||
|
@ -100,7 +119,7 @@ function canvas_flood_fill_all(_surf, _x, _y, _thres) { #region
|
||||||
for (var j = 0; j < _ff_w; j++) {
|
for (var j = 0; j < _ff_w; j++) {
|
||||||
|
|
||||||
var c = buffer_read(_ff_buff, buffer_u32);
|
var c = buffer_read(_ff_buff, buffer_u32);
|
||||||
var d = color_diff(colorBase, c, true, true);
|
var d = color_diff_alpha(colorBase, c);
|
||||||
|
|
||||||
if(d > _thres) continue;
|
if(d > _thres) continue;
|
||||||
draw_point(j, i);
|
draw_point(j, i);
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
|
|
||||||
function canvas_ms_fillable(colorBase, colorFill, _x, _y, _thres) { #region
|
function canvas_ms_fillable(colorBase, colorFill, _x, _y, _thres) { #region
|
||||||
var c = _ff_getPixel(_x, _y);
|
var c = _ff_getPixel(_x, _y);
|
||||||
var d = color_diff(colorBase, c, true, true);
|
var d = color_diff_alpha(colorBase, c);
|
||||||
return d <= _thres;
|
return d <= _thres;
|
||||||
} #endregion
|
} #endregion
|
||||||
|
|
||||||
function canvas_magic_selection_scanline(_surf, _x, _y, _thres, _corner = false) { #region
|
function canvas_magic_selection_scanline(_surf, _x, _y, _thres, _corner = false) { #region
|
||||||
|
|
||||||
var colorBase = surface_getpixel_ext(_surf, _x, _y);
|
var colorBase = int64(surface_getpixel_ext(_surf, _x, _y));
|
||||||
var colorFill = colorBase;
|
var colorFill = colorBase;
|
||||||
|
|
||||||
var x1, y1, x_start;
|
var x1, y1, x_start;
|
||||||
|
@ -19,8 +19,10 @@ function canvas_magic_selection_scanline(_surf, _x, _y, _thres, _corner = false)
|
||||||
_ff_buff = buffer_create(_ff_w * _ff_h * 4, buffer_fixed, 4);
|
_ff_buff = buffer_create(_ff_w * _ff_h * 4, buffer_fixed, 4);
|
||||||
buffer_get_surface(_ff_buff, _surf, 0);
|
buffer_get_surface(_ff_buff, _surf, 0);
|
||||||
|
|
||||||
var queue = ds_queue_create();
|
var qx = ds_queue_create();
|
||||||
ds_queue_enqueue(queue, [_x, _y]);
|
var qy = ds_queue_create();
|
||||||
|
ds_queue_enqueue(qx, _x);
|
||||||
|
ds_queue_enqueue(qy, _y);
|
||||||
|
|
||||||
var sel_x0 = surface_w;
|
var sel_x0 = surface_w;
|
||||||
var sel_y0 = surface_h;
|
var sel_y0 = surface_h;
|
||||||
|
@ -30,10 +32,10 @@ function canvas_magic_selection_scanline(_surf, _x, _y, _thres, _corner = false)
|
||||||
var _arr = array_create(surface_w * surface_h, 0);
|
var _arr = array_create(surface_w * surface_h, 0);
|
||||||
|
|
||||||
draw_set_color(c_white);
|
draw_set_color(c_white);
|
||||||
while(!ds_queue_empty(queue)) {
|
while(!ds_queue_empty(qx)) {
|
||||||
var pos = ds_queue_dequeue(queue);
|
|
||||||
x1 = pos[0];
|
x1 = ds_queue_dequeue(qx);
|
||||||
y1 = pos[1];
|
y1 = ds_queue_dequeue(qy);
|
||||||
|
|
||||||
if(_arr[y1 * surface_w + x1] == 1) continue; //Color in queue is already filled
|
if(_arr[y1 * surface_w + x1] == 1) continue; //Color in queue is already filled
|
||||||
|
|
||||||
|
@ -60,34 +62,48 @@ function canvas_magic_selection_scanline(_surf, _x, _y, _thres, _corner = false)
|
||||||
//print($"> Filling {x1}, {y1}: {canvas_get_color_buffer(x1, y1)}");
|
//print($"> Filling {x1}, {y1}: {canvas_get_color_buffer(x1, y1)}");
|
||||||
|
|
||||||
if(y1 > 0) {
|
if(y1 > 0) {
|
||||||
if(_corner && x1 > 0 && canvas_ms_fillable(colorBase, colorFill, x1 - 1, y1 - 1, thr)) //Check top left pixel
|
if(_corner && x1 > 0 && canvas_ms_fillable(colorBase, colorFill, x1 - 1, y1 - 1, thr)) { //Check top left pixel
|
||||||
ds_queue_enqueue(queue, [x1 - 1, y1 - 1]);
|
ds_queue_enqueue(qx, x1 - 1);
|
||||||
|
ds_queue_enqueue(qy, y1 - 1);
|
||||||
|
}
|
||||||
|
|
||||||
if(canvas_ms_fillable(colorBase, colorFill, x1, y1 - 1, thr)) //Check top pixel
|
if(canvas_ms_fillable(colorBase, colorFill, x1, y1 - 1, thr)) { //Check top pixel
|
||||||
ds_queue_enqueue(queue, [x1, y1 - 1]);
|
ds_queue_enqueue(qx, x1);
|
||||||
|
ds_queue_enqueue(qy, y1 - 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(y1 < surface_h - 1) {
|
if(y1 < surface_h - 1) {
|
||||||
if(_corner && x1 > 0 && canvas_ms_fillable(colorBase, colorFill, x1 - 1, y1 + 1, thr)) //Check bottom left pixel
|
if(_corner && x1 > 0 && canvas_ms_fillable(colorBase, colorFill, x1 - 1, y1 + 1, thr)) { //Check bottom left pixel
|
||||||
ds_queue_enqueue(queue, [x1 - 1, y1 + 1]);
|
ds_queue_enqueue(qx, x1 - 1);
|
||||||
|
ds_queue_enqueue(qy, y1 + 1);
|
||||||
|
}
|
||||||
|
|
||||||
if(canvas_ms_fillable(colorBase, colorFill, x1, y1 + 1, thr)) //Check bottom pixel
|
if(canvas_ms_fillable(colorBase, colorFill, x1, y1 + 1, thr)) { //Check bottom pixel
|
||||||
ds_queue_enqueue(queue, [x1, y1 + 1]);
|
ds_queue_enqueue(qx, x1);
|
||||||
|
ds_queue_enqueue(qy, y1 + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_corner && x1 < surface_w - 1) {
|
if(_corner && x1 < surface_w - 1) {
|
||||||
if(y1 > 0 && canvas_ms_fillable(colorBase, colorFill, x1 + 1, y1 - 1, thr)) //Check top right pixel
|
if(y1 > 0 && canvas_ms_fillable(colorBase, colorFill, x1 + 1, y1 - 1, thr)) { //Check top right pixel
|
||||||
ds_queue_enqueue(queue, [x1 + 1, y1 - 1]);
|
ds_queue_enqueue(qx, x1 + 1);
|
||||||
|
ds_queue_enqueue(qy, y1 - 1);
|
||||||
|
}
|
||||||
|
|
||||||
if(y1 < surface_h - 1 && canvas_ms_fillable(colorBase, colorFill, x1 + 1, y1 + 1, thr)) //Check bottom right pixel
|
if(y1 < surface_h - 1 && canvas_ms_fillable(colorBase, colorFill, x1 + 1, y1 + 1, thr)) { //Check bottom right pixel
|
||||||
ds_queue_enqueue(queue, [x1 + 1, y1 + 1]);
|
ds_queue_enqueue(qx, x1 + 1);
|
||||||
|
ds_queue_enqueue(qy, y1 + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
x1++;
|
x1++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ds_queue_destroy(queue);
|
ds_queue_destroy(qx);
|
||||||
|
ds_queue_destroy(qy);
|
||||||
|
|
||||||
buffer_delete(_ff_buff);
|
buffer_delete(_ff_buff);
|
||||||
|
|
||||||
return [ sel_x0, sel_y0, sel_x1, sel_y1 ];
|
return [ sel_x0, sel_y0, sel_x1, sel_y1 ];
|
||||||
|
@ -115,7 +131,7 @@ function canvas_magic_selection_all(_surf, _x, _y, _thres) { #region
|
||||||
for (var j = 0; j < _ff_w; j++) {
|
for (var j = 0; j < _ff_w; j++) {
|
||||||
|
|
||||||
var c = buffer_read(_ff_buff, buffer_u32);
|
var c = buffer_read(_ff_buff, buffer_u32);
|
||||||
var d = color_diff(colorBase, c, true, true);
|
var d = color_diff_alpha(colorBase, c);
|
||||||
|
|
||||||
if(d > _thres) continue;
|
if(d > _thres) continue;
|
||||||
draw_point(j, i);
|
draw_point(j, i);
|
||||||
|
|
|
@ -21,9 +21,9 @@ function canvas_tool_fill(toolAttr) : canvas_tool() constructor {
|
||||||
|
|
||||||
surface_set_target(_canvas_surface);
|
surface_set_target(_canvas_surface);
|
||||||
switch(_fill_type) {
|
switch(_fill_type) {
|
||||||
case 0 : canvas_flood_fill_scanline(_canvas_surface, mouse_cur_x, mouse_cur_y, _thr, false); break;
|
case 0 :
|
||||||
case 1 : canvas_flood_fill_scanline(_canvas_surface, mouse_cur_x, mouse_cur_y, _thr, true); break;
|
case 1 : canvas_flood_fill_scanline(_canvas_surface, mouse_cur_x, mouse_cur_y, _thr, _fill_type); break;
|
||||||
case 2 : canvas_flood_fill_all( _canvas_surface, mouse_cur_x, mouse_cur_y, _thr); break;
|
case 2 : canvas_flood_fill_all( _canvas_surface, mouse_cur_x, mouse_cur_y, _thr); break;
|
||||||
}
|
}
|
||||||
surface_reset_target();
|
surface_reset_target();
|
||||||
|
|
||||||
|
|
|
@ -153,19 +153,32 @@
|
||||||
} #endregion
|
} #endregion
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
function color_diff(c1, c2, fast = false, alpha = false) { #region
|
function color_diff_fast(c1, c2) { #region
|
||||||
var _c1_r = _color_get_red(c1);
|
INLINE
|
||||||
var _c1_g = _color_get_green(c1);
|
|
||||||
var _c1_b = _color_get_blue(c1);
|
|
||||||
var _c1_a = _color_get_alpha(c1);
|
|
||||||
|
|
||||||
var _c2_r = _color_get_red(c2);
|
return (abs(_color_get_red(c1) - _color_get_red(c2)) +
|
||||||
var _c2_g = _color_get_green(c2);
|
abs(_color_get_green(c1) - _color_get_green(c2)) +
|
||||||
var _c2_b = _color_get_blue(c2);
|
abs(_color_get_blue(c1) - _color_get_blue(c2))
|
||||||
var _c2_a = _color_get_alpha(c2);
|
) / 3;
|
||||||
|
} #endregion
|
||||||
|
|
||||||
|
function color_diff_alpha(c1, c2) { #region
|
||||||
|
INLINE
|
||||||
|
|
||||||
if(fast) return (abs(_c1_r - _c2_r) + abs(_c1_g - _c2_g) + abs(_c1_b - _c2_b)) / 3;
|
return sqrt(sqr(_color_get_red(c1) - _color_get_red(c2)) +
|
||||||
return sqrt(sqr(_c1_r - _c2_r) + sqr(_c1_g - _c2_g) + sqr(_c1_b - _c2_b));
|
sqr(_color_get_green(c1) - _color_get_green(c2)) +
|
||||||
|
sqr(_color_get_blue(c1) - _color_get_blue(c2)) +
|
||||||
|
sqr(_color_get_alpha(c1) - _color_get_alpha(c2))
|
||||||
|
);
|
||||||
|
} #endregion
|
||||||
|
|
||||||
|
function color_diff(c1, c2) { #region
|
||||||
|
INLINE
|
||||||
|
|
||||||
|
return sqrt(sqr(_color_get_red(c1) - _color_get_red(c2)) +
|
||||||
|
sqr(_color_get_green(c1) - _color_get_green(c2)) +
|
||||||
|
sqr(_color_get_blue(c1) - _color_get_blue(c2))
|
||||||
|
);
|
||||||
} #endregion
|
} #endregion
|
||||||
|
|
||||||
#region merge
|
#region merge
|
||||||
|
|
|
@ -21,11 +21,14 @@ function Node_De_Corner(_x, _y, _group = noone) : Node_Processor(_x, _y, _group)
|
||||||
|
|
||||||
__init_mask_modifier(5); // inputs 7, 8,
|
__init_mask_modifier(5); // inputs 7, 8,
|
||||||
|
|
||||||
|
inputs[| 9] = nodeValue("Include", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0b11)
|
||||||
|
.setDisplay(VALUE_DISPLAY.toggle, { data: [ "Inner", "Side" ] });
|
||||||
|
|
||||||
outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone);
|
outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone);
|
||||||
|
|
||||||
input_display_list = [ 1,
|
input_display_list = [ 1,
|
||||||
["Surfaces", true], 0, 5, 6, 7, 8,
|
["Surfaces", true], 0, 5, 6, 7, 8,
|
||||||
["Effect", false], 4, 2, 3,
|
["Effect", false], 4, 9, 2, 3,
|
||||||
]
|
]
|
||||||
|
|
||||||
attribute_surface_depth();
|
attribute_surface_depth();
|
||||||
|
@ -41,6 +44,7 @@ function Node_De_Corner(_x, _y, _group = noone) : Node_Processor(_x, _y, _group)
|
||||||
var _tol = _data[2];
|
var _tol = _data[2];
|
||||||
var _itr = _data[3];
|
var _itr = _data[3];
|
||||||
var _str = _data[4];
|
var _str = _data[4];
|
||||||
|
var _inn = _data[9];
|
||||||
|
|
||||||
var _sw = surface_get_width_safe(surf);
|
var _sw = surface_get_width_safe(surf);
|
||||||
var _sh = surface_get_height_safe(surf);
|
var _sh = surface_get_height_safe(surf);
|
||||||
|
@ -57,6 +61,8 @@ function Node_De_Corner(_x, _y, _group = noone) : Node_Processor(_x, _y, _group)
|
||||||
shader_set_f("dimension", _sw, _sh);
|
shader_set_f("dimension", _sw, _sh);
|
||||||
shader_set_f("tolerance", _tol);
|
shader_set_f("tolerance", _tol);
|
||||||
shader_set_i("strict", _str);
|
shader_set_i("strict", _str);
|
||||||
|
shader_set_i("inner", bool(_inn & 0b01));
|
||||||
|
shader_set_i("side", bool(_inn & 0b10));
|
||||||
|
|
||||||
draw_surface_safe(temp_surface[!_bg]);
|
draw_surface_safe(temp_surface[!_bg]);
|
||||||
surface_reset_shader();
|
surface_reset_shader();
|
||||||
|
|
|
@ -1,22 +1,33 @@
|
||||||
//
|
|
||||||
// Simple passthrough fragment shader
|
|
||||||
//
|
|
||||||
varying vec2 v_vTexcoord;
|
varying vec2 v_vTexcoord;
|
||||||
varying vec4 v_vColour;
|
varying vec4 v_vColour;
|
||||||
|
|
||||||
uniform vec2 dimension;
|
uniform vec2 dimension;
|
||||||
uniform float tolerance;
|
uniform float tolerance;
|
||||||
uniform int strict;
|
uniform int strict;
|
||||||
|
uniform int inner;
|
||||||
|
uniform int side;
|
||||||
|
|
||||||
float d(in vec4 c1, in vec4 c2) { return length(c1.rgb * c1.a - c2.rgb * c2.a) / sqrt(3.); }
|
float d(in vec4 c1, in vec4 c2) { return length(c1.rgb * c1.a - c2.rgb * c2.a) / sqrt(3.); }
|
||||||
bool s(in vec4 c1, in vec4 c2) { return d(c1, c2) <= tolerance; }
|
|
||||||
|
vec4 a4;
|
||||||
|
bool s(in vec4 c2) { return d(a4, c2) <= tolerance; }
|
||||||
|
bool s(in bool b, in vec4 c2) { return b || d(a4, c2) <= tolerance; }
|
||||||
|
|
||||||
|
bool s(in vec4 c1, in vec4 c2) { return d(c1, c2) <= tolerance; }
|
||||||
|
bool s(in bool b, in vec4 c1, in vec4 c2) { return b || d(c1, c2) <= tolerance; }
|
||||||
|
|
||||||
|
bool ns(in vec4 c2) { return d(a4, c2) > tolerance; }
|
||||||
|
bool ns(in bool b, in vec4 c2) { return b || d(a4, c2) > tolerance; }
|
||||||
|
|
||||||
|
bool ns(in vec4 c1, in vec4 c2) { return d(c1, c2) > tolerance; }
|
||||||
|
bool ns(in bool b, in vec4 c1, in vec4 c2) { return b || d(c1, c2) > tolerance; }
|
||||||
|
|
||||||
float bright(in vec4 c) { return dot(c.rgb, vec3(0.2126, 0.7152, 0.0722)) * c.a; }
|
float bright(in vec4 c) { return dot(c.rgb, vec3(0.2126, 0.7152, 0.0722)) * c.a; }
|
||||||
|
|
||||||
#region select closet color
|
#region select closet color
|
||||||
vec4 sel2(in vec4 c, in vec4 c0, in vec4 c1) {
|
vec4 sel2(in vec4 c0, in vec4 c1) {
|
||||||
float d0 = d(c, c0);
|
float d0 = d(a4, c0);
|
||||||
float d1 = d(c, c1);
|
float d1 = d(a4, c1);
|
||||||
|
|
||||||
float mn = min(d0, d1);
|
float mn = min(d0, d1);
|
||||||
|
|
||||||
|
@ -24,10 +35,10 @@ float bright(in vec4 c) { return dot(c.rgb, vec3(0.2126, 0.7152, 0.0722)) * c.a;
|
||||||
return c1;
|
return c1;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 sel3(in vec4 c, in vec4 c0, in vec4 c1, in vec4 c2) {
|
vec4 sel3(in vec4 c0, in vec4 c1, in vec4 c2) {
|
||||||
float d0 = d(c, c0);
|
float d0 = d(a4, c0);
|
||||||
float d1 = d(c, c1);
|
float d1 = d(a4, c1);
|
||||||
float d2 = d(c, c2);
|
float d2 = d(a4, c2);
|
||||||
|
|
||||||
float mn = min(min(d0, d1), d2);
|
float mn = min(min(d0, d1), d2);
|
||||||
|
|
||||||
|
@ -36,11 +47,11 @@ float bright(in vec4 c) { return dot(c.rgb, vec3(0.2126, 0.7152, 0.0722)) * c.a;
|
||||||
return c2;
|
return c2;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 sel4(in vec4 c, in vec4 c0, in vec4 c1, in vec4 c2, in vec4 c3) {
|
vec4 sel4(in vec4 c0, in vec4 c1, in vec4 c2, in vec4 c3) {
|
||||||
float d0 = d(c, c0);
|
float d0 = d(a4, c0);
|
||||||
float d1 = d(c, c1);
|
float d1 = d(a4, c1);
|
||||||
float d2 = d(c, c2);
|
float d2 = d(a4, c2);
|
||||||
float d3 = d(c, c3);
|
float d3 = d(a4, c3);
|
||||||
|
|
||||||
float mn = min(min(d0, d1), min(d2, d3));
|
float mn = min(min(d0, d1), min(d2, d3));
|
||||||
|
|
||||||
|
@ -63,7 +74,7 @@ void main() {
|
||||||
// 3 4 5
|
// 3 4 5
|
||||||
// 6 7 8
|
// 6 7 8
|
||||||
|
|
||||||
vec4 a4 = texture2D( gm_BaseTexture, v_vTexcoord );
|
a4 = texture2D( gm_BaseTexture, v_vTexcoord );
|
||||||
vec2 tx = 1. / dimension;
|
vec2 tx = 1. / dimension;
|
||||||
gl_FragColor = a4;
|
gl_FragColor = a4;
|
||||||
|
|
||||||
|
@ -80,62 +91,65 @@ void main() {
|
||||||
vec4 a7 = sample( v_vTexcoord + vec2( 0., tx.y) );
|
vec4 a7 = sample( v_vTexcoord + vec2( 0., tx.y) );
|
||||||
vec4 a8 = sample( v_vTexcoord + vec2( tx.x, tx.y) );
|
vec4 a8 = sample( v_vTexcoord + vec2( tx.x, tx.y) );
|
||||||
|
|
||||||
|
bool n = inner == 0;
|
||||||
|
bool d = side == 0;
|
||||||
|
|
||||||
if(strict == 0) {
|
if(strict == 0) {
|
||||||
|
|
||||||
if(s(a4, a0) && s(a4, a1) && s(a4, a3) && !s(a4, a2) && !s(a4, a5) && !s(a4, a6) && !s(a4, a7) && !s(a4, a8)) { // A A 2
|
if(s(n, a0) && s(a1) && s(a3) && ns(d, a2) && ns(d, a5) && ns(d, a6) && ns(d, a7) && ns(a8)) { // A A 2
|
||||||
// A A 5
|
// A A 5
|
||||||
// 6 7 8
|
// 6 7 8
|
||||||
gl_FragColor = sel3(a4, sel2(a4, a2, a6), sel2(a4, a5, a7), a8);
|
gl_FragColor = n? sel3(a5, a7, a8) : sel3(sel2(a2, a6), sel2(a5, a7), a8);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(s(a4, a1) && s(a4, a2) && s(a4, a5) && !s(a4, a0) && !s(a4, a3) && !s(a4, a6) && !s(a4, a7) && !s(a4, a8)) { // 0 A A
|
if(s(a1) && s(n, a2) && s(a5) && ns(d, a0) && ns(d, a3) && ns(a6) && ns(d, a7) && ns(d, a8)) { // 0 A A
|
||||||
// 3 A A
|
// 3 A A
|
||||||
// 6 7 8
|
// 6 7 8
|
||||||
gl_FragColor = sel3(a4, sel2(a4, a0, a8), sel2(a4, a3, a7), a6);
|
gl_FragColor = n? sel3(a3, a6, a7) : sel3(sel2(a0, a8), sel2(a3, a7), a6);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(s(a4, a3) && s(a4, a6) && s(a4, a7) && !s(a4, a0) && !s(a4, a1) && !s(a4, a2) && !s(a4, a5) && !s(a4, a8)) { // 0 1 2
|
if(s(a3) && s(n, a6) && s(a7) && ns(d, a0) && ns(d, a1) && ns(a2) && ns(d, a5) && ns(d, a8)) { // 0 1 2
|
||||||
// A A 5
|
// A A 5
|
||||||
// A A 8
|
// A A 8
|
||||||
gl_FragColor = sel3(a4, sel2(a4, a0, a8), sel2(a4, a1, a5), a2);
|
gl_FragColor = n? sel3(a1, a2, a5) : sel3(sel2(a0, a8), sel2(a1, a5), a2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(s(a4, a5) && s(a4, a7) && s(a4, a8) && !s(a4, a0) && !s(a4, a1) && !s(a4, a2) && !s(a4, a3) && !s(a4, a6)) { // 0 1 2
|
if(s(a5) && s(a7) && s(n, a8) && ns(a0) && ns(d, a1) && ns(d, a2) && ns(d, a3) && ns(d, a6)) { // 0 1 2
|
||||||
// 3 A A
|
// 3 A A
|
||||||
// 6 A A
|
// 6 A A
|
||||||
gl_FragColor = sel3(a4, sel2(a4, a2, a6), sel2(a4, a1, a3), a0);
|
gl_FragColor = n? sel3(a0, a1, a3) : sel3(sel2(a2, a6), sel2(a1, a3), a0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if(strict == 1) {
|
} else if(strict == 1) {
|
||||||
if(s(a5, a7) && s(a4, a1) && s(a4, a3) && s(a4, a0) && !s(a4, a2) && !s(a4, a5) && !s(a4, a6) && !s(a4, a7)) { // B B C
|
if(s(a5, a7) && s(a1) && s(a3) && s(n, a0) && ns(d, a2) && ns(d, a5) && ns(d, a6) && ns(d, a7)) { // B B C
|
||||||
// B B A
|
// B B A
|
||||||
// C A 8
|
// C A 8
|
||||||
gl_FragColor = sel3(a4, sel2(a4, a2, a6), sel2(a4, a5, a7), a8);
|
gl_FragColor = n? sel3(a5, a7, a8) : sel3(sel2(a2, a6), sel2(a5, a7), a8);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(s(a3, a7) && s(a4, a1) && s(a4, a2) && s(a4, a5) && !s(a4, a0) && !s(a4, a3) && !s(a4, a7) && !s(a4, a8)) { // C B B
|
if(s(a3, a7) && s(a1) && s(n, a2) && s(a5) && ns(d, a0) && ns(d, a3) && ns(d, a7) && ns(d, a8)) { // C B B
|
||||||
// A B B
|
// A B B
|
||||||
// 6 A C
|
// 6 A C
|
||||||
gl_FragColor = sel3(a4, sel2(a4, a0, a8), sel2(a4, a3, a7), a6);
|
gl_FragColor = n? sel3(a3, a6, a7) : sel3(sel2(a0, a8), sel2(a3, a7), a6);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(s(a5, a1) && s(a4, a3) && s(a4, a6) && s(a4, a7) && !s(a4, a0) && !s(a4, a1) && !s(a4, a5) && !s(a4, a8)) { // C A 2
|
if(s(a5, a1) && s(a3) && s(n, a6) && s(a7) && ns(d, a0) && ns(d, a1) && ns(d, a5) && ns(d, a8)) { // C A 2
|
||||||
// B B A
|
// B B A
|
||||||
// B B C
|
// B B C
|
||||||
gl_FragColor = sel3(a4, sel2(a4, a0, a8), sel2(a4, a1, a5), a2);
|
gl_FragColor = n? sel3(a1, a2, a5) : sel3(sel2(a0, a8), sel2(a1, a5), a2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(s(a3, a1) && s(a4, a5) && s(a4, a8) && s(a4, a7) && !s(a4, a2) && !s(a4, a1) && !s(a4, a3) && !s(a4, a6)) { // 0 A C
|
if(s(a3, a1) && s(a5) && s(n, a8) && s(a7) && ns(d, a2) && ns(d, a1) && ns(d, a3) && ns(d, a6)) { // 0 A C
|
||||||
// A B B
|
// A B B
|
||||||
// C B B
|
// C B B
|
||||||
gl_FragColor = sel3(a4, sel2(a4, a2, a6), sel2(a4, a1, a3), a0);
|
gl_FragColor = n? sel3(a0, a1, a3) : sel3(sel2(a2, a6), sel2(a1, a3), a0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue