mirror of
https://github.com/Ttanasart-pt/Pixel-Composer.git
synced 2024-12-24 14:06:23 +01:00
path builder, file exp, dither noise
This commit is contained in:
parent
58ef98f8a8
commit
a0a1941159
22 changed files with 388 additions and 198 deletions
|
@ -136,6 +136,7 @@
|
|||
{"name":"color","order":42,"path":"folders/shader/filter/color.yy",},
|
||||
{"name":"corner","order":43,"path":"folders/shader/filter/corner.yy",},
|
||||
{"name":"edge_shade","order":44,"path":"folders/shader/filter/edge_shade.yy",},
|
||||
{"name":"dither","order":53,"path":"folders/shader/filter/dither.yy",},
|
||||
{"name":"morph","order":45,"path":"folders/shader/filter/morph.yy",},
|
||||
{"name":"shadow_caster","order":46,"path":"folders/shader/filter/shadow_caster.yy",},
|
||||
{"name":"shape_seperator","order":47,"path":"folders/shader/filter/shape_seperator.yy",},
|
||||
|
@ -1295,7 +1296,7 @@
|
|||
{"name":"sh_diffuse_post","order":2,"path":"shaders/sh_diffuse_post/sh_diffuse_post.yy",},
|
||||
{"name":"sh_dilate","order":4,"path":"shaders/sh_dilate/sh_dilate.yy",},
|
||||
{"name":"sh_displace","order":5,"path":"shaders/sh_displace/sh_displace.yy",},
|
||||
{"name":"sh_dither","order":14,"path":"shaders/sh_dither/sh_dither.yy",},
|
||||
{"name":"sh_dither_screen","order":1,"path":"shaders/sh_dither_screen/sh_dither_screen.yy",},
|
||||
{"name":"sh_downsample","order":1,"path":"shaders/sh_downsample/sh_downsample.yy",},
|
||||
{"name":"sh_draw_color","order":8,"path":"shaders/sh_draw_color/sh_draw_color.yy",},
|
||||
{"name":"sh_draw_divide","order":12,"path":"shaders/sh_draw_divide/sh_draw_divide.yy",},
|
||||
|
|
|
@ -265,6 +265,7 @@
|
|||
{"$GMFolder":"","%Name":"color","folderPath":"folders/shader/filter/color.yy","name":"color","resourceType":"GMFolder","resourceVersion":"2.0",},
|
||||
{"$GMFolder":"","%Name":"corner","folderPath":"folders/shader/filter/corner.yy","name":"corner","resourceType":"GMFolder","resourceVersion":"2.0",},
|
||||
{"$GMFolder":"","%Name":"edge_shade","folderPath":"folders/shader/filter/edge_shade.yy","name":"edge_shade","resourceType":"GMFolder","resourceVersion":"2.0",},
|
||||
{"$GMFolder":"","%Name":"dither","folderPath":"folders/shader/filter/dither.yy","name":"dither","resourceType":"GMFolder","resourceVersion":"2.0",},
|
||||
{"$GMFolder":"","%Name":"morph","folderPath":"folders/shader/filter/morph.yy","name":"morph","resourceType":"GMFolder","resourceVersion":"2.0",},
|
||||
{"$GMFolder":"","%Name":"shadow_caster","folderPath":"folders/shader/filter/shadow_caster.yy","name":"shadow_caster","resourceType":"GMFolder","resourceVersion":"2.0",},
|
||||
{"$GMFolder":"","%Name":"shape_seperator","folderPath":"folders/shader/filter/shape_seperator.yy","name":"shape_seperator","resourceType":"GMFolder","resourceVersion":"2.0",},
|
||||
|
@ -1801,6 +1802,7 @@
|
|||
{"id":{"name":"sh_diffuse_post","path":"shaders/sh_diffuse_post/sh_diffuse_post.yy",},},
|
||||
{"id":{"name":"sh_dilate","path":"shaders/sh_dilate/sh_dilate.yy",},},
|
||||
{"id":{"name":"sh_displace","path":"shaders/sh_displace/sh_displace.yy",},},
|
||||
{"id":{"name":"sh_dither_screen","path":"shaders/sh_dither_screen/sh_dither_screen.yy",},},
|
||||
{"id":{"name":"sh_dither","path":"shaders/sh_dither/sh_dither.yy",},},
|
||||
{"id":{"name":"sh_downsample","path":"shaders/sh_downsample/sh_downsample.yy",},},
|
||||
{"id":{"name":"sh_draw_color","path":"shaders/sh_draw_color/sh_draw_color.yy",},},
|
||||
|
|
Binary file not shown.
|
@ -8,7 +8,6 @@ function FileObject(_name, _path) constructor { #region
|
|||
sprFetchID = noone;
|
||||
|
||||
content = -1;
|
||||
surface = noone;
|
||||
|
||||
var _mdir = filename_dir(path);
|
||||
var _mname = filename_name_only(path);
|
||||
|
@ -35,13 +34,6 @@ function FileObject(_name, _path) constructor { #region
|
|||
|
||||
static getName = function() { return name; }
|
||||
|
||||
static getSurface = function() { #region
|
||||
if(is_surface(surface)) return surface;
|
||||
var spr = getSpr();
|
||||
surface = surface_create_from_sprite_ext(spr, 0);
|
||||
return surface;
|
||||
} #endregion
|
||||
|
||||
static getThumbnail = function() { #region
|
||||
if(thumbnail != noone && is_surface(thumbnail)) return thumbnail; // Thumbnail loaded
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ function Node_Array(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
|
|||
return _h;
|
||||
}); #endregion
|
||||
|
||||
input_display_list = [ 0, array_adjust_tool, 1 ];
|
||||
input_display_list = [ 0, 1, ["Contents", false], array_adjust_tool, ];
|
||||
|
||||
setIsDynamicInput(1);
|
||||
|
||||
|
@ -102,15 +102,15 @@ function Node_Array(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
|
|||
ds_list_add(_l, lastNode);
|
||||
}
|
||||
|
||||
input_display_list = [];
|
||||
for( var i = 0; i < ds_list_size(_l); i++ ) {
|
||||
input_display_list = array_clone(input_display_list_raw);
|
||||
|
||||
for( var i = input_fix_len; i < ds_list_size(_l); i++ ) {
|
||||
_l[| i].index = i;
|
||||
array_push(input_display_list, i);
|
||||
|
||||
if(i >= input_fix_len && _l[| i].value_from == noone)
|
||||
if(_l[| i].value_from == noone)
|
||||
extra = false;
|
||||
}
|
||||
array_insert(input_display_list, 1, array_adjust_tool);
|
||||
|
||||
ds_list_destroy(inputs);
|
||||
inputs = _l;
|
||||
|
|
|
@ -443,6 +443,8 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
|
|||
static setIsDynamicInput = function(_data_length = 1, _auto_input = true, _dynamic_input_cond = DYNA_INPUT_COND.connection) { #region
|
||||
is_dynamic_input = true;
|
||||
auto_input = _auto_input;
|
||||
|
||||
input_display_list_raw = array_clone(input_display_list);
|
||||
input_display_len = input_display_list == -1? 0 : array_length(input_display_list);
|
||||
input_fix_len = ds_list_size(inputs);
|
||||
data_length = _data_length;
|
||||
|
@ -554,10 +556,23 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
|
|||
static onInspector1Update = noone;
|
||||
static inspector1Update = function() { INLINE onInspector1Update(); }
|
||||
static hasInspector1Update = function() { INLINE return NODE_HAS_INSP1; }
|
||||
|
||||
|
||||
static onInspector2Update = noone;
|
||||
static inspector2Update = function() { INLINE onInspector2Update(); }
|
||||
static hasInspector2Update = function() { INLINE return NODE_HAS_INSP2; }
|
||||
|
||||
static setInspector = function(index, _tooltip, _icon, _function) {
|
||||
if(index == 1) {
|
||||
insp1UpdateTooltip = _tooltip;
|
||||
insp1UpdateIcon = _icon;
|
||||
onInspector1Update = _function;
|
||||
|
||||
} else if(index == 2) {
|
||||
insp2UpdateTooltip = _tooltip;
|
||||
insp2UpdateIcon = _icon;
|
||||
onInspector2Update = _function;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
static stepBegin = function() { #region
|
||||
|
|
|
@ -22,7 +22,7 @@ function Node_Dither(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) co
|
|||
.setDisplay(VALUE_DISPLAY.palette);
|
||||
|
||||
inputs[| 2] = nodeValue("Pattern", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0)
|
||||
.setDisplay(VALUE_DISPLAY.enum_scroll, [ "2 x 2 Bayer", "4 x 4 Bayer", "8 x 8 Bayer", "Custom" ]);
|
||||
.setDisplay(VALUE_DISPLAY.enum_scroll, [ "2 x 2 Bayer", "4 x 4 Bayer", "8 x 8 Bayer", "White Noise", "Custom" ]);
|
||||
|
||||
inputs[| 3] = nodeValue("Dither map", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone)
|
||||
.setVisible(false);
|
||||
|
@ -48,9 +48,12 @@ function Node_Dither(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) co
|
|||
|
||||
__init_mask_modifier(7); // inputs 11, 12,
|
||||
|
||||
inputs[| 13] = nodeValue("Seed", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, seed_random(6))
|
||||
.setDisplay(VALUE_DISPLAY._default, { side_button : button(function() { inputs[| 13].setValue(seed_random(6)); }).setIcon(THEME.icon_random, 0, COLORS._main_icon) });
|
||||
|
||||
outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone);
|
||||
|
||||
input_display_list = [ 9, 10,
|
||||
input_display_list = [ 9, 10, 13,
|
||||
["Surfaces", true], 0, 7, 8, 11, 12,
|
||||
["Pattern", false], 2, 3,
|
||||
["Dither", false], 6, 1, 4, 5
|
||||
|
@ -64,7 +67,7 @@ function Node_Dither(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) co
|
|||
var _type = getInputData(2);
|
||||
var _mode = getInputData(6);
|
||||
|
||||
inputs[| 3].setVisible(_type == 3, _type == 3);
|
||||
inputs[| 3].setVisible(_type == 4, _type == 4);
|
||||
inputs[| 1].setVisible(_mode == 0);
|
||||
inputs[| 4].setVisible(_mode == 0);
|
||||
inputs[| 5].setVisible(_mode == 0);
|
||||
|
@ -77,6 +80,7 @@ function Node_Dither(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) co
|
|||
var _con = _data[4];
|
||||
var _conMap = _data[5];
|
||||
var _mode = _data[6];
|
||||
var _seed = _data[13];
|
||||
|
||||
surface_set_shader(_outSurf, _mode? sh_alpha_hash : sh_dither);
|
||||
shader_set_f("dimension", surface_get_dimension(_data[0]));
|
||||
|
@ -87,17 +91,25 @@ function Node_Dither(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) co
|
|||
shader_set_f("ditherSize", 2);
|
||||
shader_set_f("dither", dither2);
|
||||
break;
|
||||
|
||||
case 1 :
|
||||
shader_set_i("useMap", 0);
|
||||
shader_set_f("ditherSize", 4);
|
||||
shader_set_f("dither", dither4);
|
||||
break;
|
||||
|
||||
case 2 :
|
||||
shader_set_i("useMap", 0);
|
||||
shader_set_f("ditherSize", 8);
|
||||
shader_set_f("dither", dither8);
|
||||
break;
|
||||
|
||||
case 3 :
|
||||
shader_set_i("useMap", 2);
|
||||
shader_set_f("seed", _seed);
|
||||
break;
|
||||
|
||||
case 4 :
|
||||
if(is_surface(_map)) {
|
||||
shader_set_i("useMap", 1);
|
||||
shader_set_f("mapDimension", surface_get_dimension(_map));
|
||||
|
|
|
@ -90,10 +90,7 @@ function Node_Path(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
|
|||
static resetDisplayList = function() { #region
|
||||
recordAction(ACTION_TYPE.var_modify, self, [ array_clone(input_display_list), "input_display_list" ]);
|
||||
|
||||
input_display_list = [
|
||||
["Path", false], 0, 2, 1, 3,
|
||||
["Anchors", false],
|
||||
];
|
||||
input_display_list = array_clone(input_display_list_raw);
|
||||
|
||||
for( var i = input_fix_len, n = ds_list_size(inputs); i < n; i++ ) {
|
||||
array_push(input_display_list, i);
|
||||
|
@ -808,12 +805,11 @@ function Node_Path(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
|
|||
lengthTotal = 0;
|
||||
|
||||
var _index = 0;
|
||||
var loop = getInputData(1);
|
||||
var sample = PREFERENCES.path_resolution;
|
||||
var ansize = ds_list_size(inputs) - input_fix_len;
|
||||
if(ansize < 2) return;
|
||||
|
||||
var con = loop? ansize : ansize - 1;
|
||||
var con = path_loop? ansize : ansize - 1;
|
||||
|
||||
for(var i = 0; i < con; i++) {
|
||||
var _a0 = anchors[(i + 0) % ansize];
|
||||
|
|
|
@ -2,15 +2,26 @@ function Node_Path_Builder(_x, _y, _group = noone) : Node(_x, _y, _group) constr
|
|||
name = "Path Builder";
|
||||
setDimension(96, 48);;
|
||||
|
||||
length = [];
|
||||
lengthAcc = [];
|
||||
#region ---- path ----
|
||||
path_loop = false;
|
||||
anchors = [];
|
||||
segments = [];
|
||||
lengths = [];
|
||||
lengthAccs = [];
|
||||
lengthTotal = 0;
|
||||
boundary = new BoundingBox();
|
||||
|
||||
lines = [];
|
||||
cached_pos = ds_map_create();
|
||||
|
||||
lines = [];
|
||||
#endregion
|
||||
|
||||
inputs[| 0] = nodeValue("Point array", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [])
|
||||
.setVisible(true, true)
|
||||
.setArrayDepth(2);
|
||||
|
||||
inputs[| 1] = nodeValue("Loop", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false);
|
||||
|
||||
outputs[| 0] = nodeValue("Path", self, JUNCTION_CONNECT.output, VALUE_TYPE.pathnode, self);
|
||||
|
||||
cached_pos = ds_map_create();
|
||||
|
@ -18,31 +29,94 @@ function Node_Path_Builder(_x, _y, _group = noone) : Node(_x, _y, _group) constr
|
|||
static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { #region
|
||||
draw_set_color(COLORS._main_accent);
|
||||
|
||||
for( var i = 0, n = array_length(lines); i < n; i++ ) {
|
||||
var _line = lines[i];
|
||||
if(!array_empty(anchors)) {
|
||||
draw_set_color(COLORS._main_accent);
|
||||
|
||||
for( var j = 1, m = array_length(_line); j < m; j++ ) {
|
||||
var p0 = _line[j - 1];
|
||||
var p1 = _line[j - 0];
|
||||
for( var i = 0, n = array_length(segments); i < n; i++ ) { #region draw path
|
||||
var _seg = segments[i];
|
||||
var _ox = 0, _oy = 0, _nx = 0, _ny = 0, p = 0;
|
||||
|
||||
for( var j = 0, m = array_length(_seg); j < m; j++ ) {
|
||||
_nx = _x + _seg[j][0] * _s;
|
||||
_ny = _y + _seg[j][1] * _s;
|
||||
|
||||
if(j) draw_line_width(_ox, _oy, _nx, _ny, 1);
|
||||
|
||||
_ox = _nx;
|
||||
_oy = _ny;
|
||||
}
|
||||
} #endregion
|
||||
|
||||
#region draw anchor
|
||||
for(var i = 0; i < array_length(anchors); i++) {
|
||||
var _a = anchors[i];
|
||||
var xx = _x + _a[0] * _s;
|
||||
var yy = _y + _a[1] * _s;
|
||||
|
||||
draw_sprite_colored(THEME.anchor_selector, 0, xx, yy);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
if(inputs[| 0].value_from != noone)
|
||||
inputs[| 0].drawOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny);
|
||||
} #endregion
|
||||
|
||||
static updateLength = function() { #region
|
||||
boundary = new BoundingBox();
|
||||
segments = [];
|
||||
lengths = [];
|
||||
lengthAccs = [];
|
||||
lengthTotal = 0;
|
||||
|
||||
var _index = 0;
|
||||
var sample = PREFERENCES.path_resolution;
|
||||
var ansize = array_length(anchors);
|
||||
if(ansize < 2) return;
|
||||
|
||||
var con = path_loop? ansize : ansize - 1;
|
||||
|
||||
for(var i = 0; i < con; i++) {
|
||||
var _a0 = anchors[(i + 0) % ansize];
|
||||
var _a1 = anchors[(i + 1) % ansize];
|
||||
|
||||
var l = 0, _ox = 0, _oy = 0, _nx = 0, _ny = 0, p = 0;
|
||||
var sg = array_create(sample);
|
||||
|
||||
for(var j = 0; j <= sample; j++) {
|
||||
p = eval_bezier(j / sample, _a0[0], _a0[1], _a1[0], _a1[1],
|
||||
_a0[0] + _a0[4], _a0[1] + _a0[5],
|
||||
_a1[0] + _a1[2], _a1[1] + _a1[3]);
|
||||
sg[j] = p;
|
||||
_nx = p[0];
|
||||
_ny = p[1];
|
||||
|
||||
draw_line(_x + p0[0] * _s, _y + p0[1] * _s,
|
||||
_x + p1[0] * _s, _y + p1[1] * _s);
|
||||
|
||||
if(j == 1) draw_circle(_x + p0[0] * _s, _y + p0[1] * _s, 4, false);
|
||||
draw_circle(_x + p1[0] * _s, _y + p1[1] * _s, 4, false);
|
||||
boundary.addPoint(_nx, _ny);
|
||||
if(j) l += point_distance(_nx, _ny, _ox, _oy);
|
||||
|
||||
_ox = _nx;
|
||||
_oy = _ny;
|
||||
}
|
||||
|
||||
segments[i] = sg;
|
||||
lengths[i] = l;
|
||||
lengthTotal += l;
|
||||
lengthAccs[i] = lengthTotal;
|
||||
}
|
||||
} #endregion
|
||||
|
||||
static getLineCount = function() { return array_length(lines); }
|
||||
static getSegmentCount = function() { return array_length(lines); }
|
||||
static getLength = function(index) { return array_safe_get_fast(length, index); }
|
||||
static getAccuLength = function(index) { return array_safe_get_fast(lengthAcc, index, []); }
|
||||
static getLineCount = function() { return 1; }
|
||||
static getSegmentCount = function() { return array_length(lengths); }
|
||||
static getBoundary = function() { return boundary; }
|
||||
|
||||
static getPointRatio = function(_rat, _ind = 0, out = undefined) { #region
|
||||
static getLength = function() { return lengthTotal; }
|
||||
static getAccuLength = function() { return lengthAccs; }
|
||||
|
||||
static getPointDistance = function(_dist, _ind = 0, out = undefined) { #region
|
||||
if(out == undefined) out = new __vec2(); else { out.x = 0; out.y = 0; }
|
||||
if(array_empty(lengths)) return out;
|
||||
|
||||
var _cKey = $"{_rat},{_ind}";
|
||||
var _cKey = _dist;
|
||||
if(ds_map_exists(cached_pos, _cKey)) {
|
||||
var _p = cached_pos[? _cKey];
|
||||
out.x = _p.x;
|
||||
|
@ -50,83 +124,57 @@ function Node_Path_Builder(_x, _y, _group = noone) : Node(_x, _y, _group) constr
|
|||
return out;
|
||||
}
|
||||
|
||||
var _p0, _p1;
|
||||
var _x, _y;
|
||||
var loop = getInputData(1);
|
||||
if(loop) _dist = safe_mod(_dist, lengthTotal, MOD_NEG.wrap);
|
||||
|
||||
var line = array_safe_get_fast(lines, _ind, []);
|
||||
var _st = _rat * (array_length(line) - 1);
|
||||
_p0 = array_safe_get_fast(line, floor(_st) + 0);
|
||||
_p1 = array_safe_get_fast(line, floor(_st) + 1);
|
||||
var ansize = ds_list_size(inputs) - input_fix_len;
|
||||
if(ansize == 0) return out;
|
||||
|
||||
if(!is_array(_p0)) return out;
|
||||
if(!is_array(_p1)) return out;
|
||||
var _a0, _a1;
|
||||
|
||||
for(var i = 0; i < ansize; i++) {
|
||||
_a0 = anchors[(i + 0) % ansize];
|
||||
_a1 = anchors[(i + 1) % ansize];
|
||||
|
||||
out.x = lerp(_p0[0], _p1[0], frac(_st));
|
||||
out.y = lerp(_p0[1], _p1[1], frac(_st));
|
||||
|
||||
cached_pos[? _cKey] = out.clone();
|
||||
if(_dist > lengths[i]) {
|
||||
_dist -= lengths[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
var _t = _dist / lengths[i];
|
||||
var _p = eval_bezier(_t, _a0[0], _a0[1], _a1[0], _a1[1], _a0[0] + _a0[4], _a0[1] + _a0[5], _a1[0] + _a1[2], _a1[1] + _a1[3]);
|
||||
out.x = _p[0];
|
||||
out.y = _p[1];
|
||||
|
||||
cached_pos[? _cKey] = out.clone();
|
||||
return out;
|
||||
}
|
||||
|
||||
return out;
|
||||
} #endregion
|
||||
|
||||
static getPointDistance = function(_dist, ind = 0, out = undefined) { return getPointRatio(_dist / length[ind], ind, out); }
|
||||
|
||||
static getBoundary = function() { #region
|
||||
var boundary = new BoundingBox();
|
||||
|
||||
for( var i = 0, n = array_length(lines); i < n; i++ ) {
|
||||
var _line = lines[i];
|
||||
for( var j = 0, m = array_length(_line); j < m; j++ )
|
||||
boundary.addPoint(_line[j][0], _line[j][1]);
|
||||
}
|
||||
|
||||
return boundary;
|
||||
static getPointRatio = function(_rat, _ind = 0, out = undefined) { #region
|
||||
var pix = (path_loop? frac(_rat) : clamp(_rat, 0, 0.99)) * lengthTotal;
|
||||
return getPointDistance(pix, _ind, out);
|
||||
} #endregion
|
||||
|
||||
static update = function() { #region
|
||||
ds_map_clear(cached_pos);
|
||||
var _lines = getInputData(0);
|
||||
if(array_empty(_lines)) return;
|
||||
|
||||
lines = _lines;
|
||||
if(!is_array(_lines[0][0]))
|
||||
lines = [ lines ];
|
||||
var _anc = getInputData(0);
|
||||
path_loop = getInputData(1);
|
||||
|
||||
var _len = array_length(lines);
|
||||
length = array_create(_len);
|
||||
lengthAcc = array_create(_len);
|
||||
anchors = array_create(array_length(_anc));
|
||||
|
||||
for( var i = 0; i < _len; i++ ) {
|
||||
var _line = lines[i];
|
||||
var _lngh = 0;
|
||||
var _lenA = [];
|
||||
for (var i = 0, n = array_length(_anc); i < n; i++) {
|
||||
var _a = _anc[i];
|
||||
|
||||
var _ox = _line[0], _nx;
|
||||
|
||||
for( var j = 1, m = array_length(_line); j < m; j++ ) {
|
||||
_nx = _line[j];
|
||||
|
||||
var p0x = array_safe_get_fast(_ox, 0);
|
||||
var p0y = array_safe_get_fast(_ox, 1);
|
||||
var p1x = array_safe_get_fast(_nx, 0);
|
||||
var p1y = array_safe_get_fast(_nx, 1);
|
||||
|
||||
p0x = is_real(p0x)? p0x : 0;
|
||||
p0y = is_real(p0y)? p0y : 0;
|
||||
p1x = is_real(p1x)? p1x : 0;
|
||||
p1y = is_real(p1y)? p1y : 0;
|
||||
|
||||
var dist = point_distance(p0x, p0y, p1x, p1y);
|
||||
_lngh += dist;
|
||||
array_push(_lenA, dist);
|
||||
|
||||
_ox = _nx;
|
||||
}
|
||||
|
||||
length[i] = _lngh;
|
||||
lengthAcc[i] = _lenA;
|
||||
for(var j = 0; j < 7; j++)
|
||||
anchors[i][j] = array_safe_get(_a, j, 0);
|
||||
}
|
||||
|
||||
updateLength();
|
||||
|
||||
outputs[| 0].setValue(self);
|
||||
} #endregion
|
||||
|
||||
|
|
|
@ -5,45 +5,62 @@ function Node_Websocket_Receiver(_x, _y, _group = noone) : Node(_x, _y, _group)
|
|||
|
||||
inputs[| 1] = nodeValue("Active", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, true);
|
||||
|
||||
inputs[| 2] = nodeValue("Mode", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 1)
|
||||
.setDisplay(VALUE_DISPLAY.enum_button, [ "Client", "Server" ]);
|
||||
|
||||
inputs[| 3] = nodeValue("Url", self, JUNCTION_CONNECT.input, VALUE_TYPE.text, "");
|
||||
|
||||
outputs[| 0] = nodeValue("Data", self, JUNCTION_CONNECT.output, VALUE_TYPE.struct, {});
|
||||
|
||||
outputs[| 1] = nodeValue("Receive data", self, JUNCTION_CONNECT.output, VALUE_TYPE.trigger, false);
|
||||
|
||||
input_display_list = [ 1, 0 ];
|
||||
input_display_list = [ 1, 2,
|
||||
["Connection", false], 0, 3,
|
||||
];
|
||||
|
||||
connected_device = 0;
|
||||
network_trigger = 0;
|
||||
port = 0;
|
||||
mode = 0;
|
||||
url = "";
|
||||
socket = noone;
|
||||
client = noone;
|
||||
|
||||
function setPort(newPort) { #region
|
||||
function setPort() { #region
|
||||
|
||||
var _port = getInputData(0);
|
||||
var _mode = getInputData(2);
|
||||
var _url = getInputData(3);
|
||||
|
||||
if(_port == port && _mode == mode && _url == url) return;
|
||||
|
||||
port = _port;
|
||||
mode = _mode;
|
||||
url = _url;
|
||||
|
||||
if(ds_map_exists(PORT_MAP, port))
|
||||
array_remove(PORT_MAP[? port], self);
|
||||
|
||||
port = newPort;
|
||||
if(!ds_map_exists(PORT_MAP, port))
|
||||
PORT_MAP[? port] = [];
|
||||
array_push(PORT_MAP[? port], self);
|
||||
|
||||
if(ds_map_exists(NETWORK_SERVERS, port))
|
||||
return;
|
||||
|
||||
if(socket >= 0) network_destroy(socket);
|
||||
socket = network_create_server_raw(network_socket_ws, port, 16)
|
||||
if(socket < 0) return;
|
||||
|
||||
NETWORK_SERVERS[? newPort] = socket;
|
||||
if(socket != noone)
|
||||
network_destroy(socket);
|
||||
|
||||
if(mode == 0) {
|
||||
client = network_create_socket(network_socket_ws);
|
||||
network_connect_raw(client, url, port);
|
||||
|
||||
} else if(mode == 1) {
|
||||
socket = network_create_server_raw(network_socket_ws, port, 16);
|
||||
if(socket)
|
||||
NETWORK_SERVERS[? newPort] = socket;
|
||||
}
|
||||
} #endregion
|
||||
|
||||
insp1UpdateTooltip = __txt("Refresh Server");
|
||||
insp1UpdateIcon = [ THEME.refresh_icon, 1, COLORS._main_value_positive ];
|
||||
setInspector(1, __txt("Refresh Server"), [ THEME.refresh_icon, 1, COLORS._main_value_positive ], function() { setPort(); });
|
||||
|
||||
static onInspector1Update = function() { #region
|
||||
var _port = getInputData(0);
|
||||
|
||||
setPort(_port);
|
||||
} #endregion
|
||||
|
||||
network_trigger = 0;
|
||||
static asyncPackets = function(_async_load) { #region
|
||||
if(!active) return;
|
||||
|
||||
|
@ -57,18 +74,20 @@ function Node_Websocket_Receiver(_x, _y, _group = noone) : Node(_x, _y, _group)
|
|||
noti_status($"Websocket server: Client connected at port {port} on node {display_name}");
|
||||
connected_device++;
|
||||
break;
|
||||
|
||||
case network_type_disconnect :
|
||||
noti_status($"Websocket server: Client disconnected at port {port} on node {display_name}");
|
||||
connected_device--;
|
||||
break;
|
||||
|
||||
case network_type_data :
|
||||
var buffer = async_load[? "buffer"];
|
||||
var socket = async_load[? "id"];
|
||||
var data = buffer_get_string(buffer);
|
||||
var _buffer = async_load[? "buffer"];
|
||||
var _socket = async_load[? "id"];
|
||||
var data = buffer_get_string(_buffer);
|
||||
|
||||
var _data = json_try_parse(data, noone);
|
||||
if(_data == noone) _data = { rawData: new Buffer(buffer) }
|
||||
else buffer_delete(buffer);
|
||||
if(_data == noone) _data = { rawData: new Buffer(_buffer) }
|
||||
else buffer_delete(_buffer);
|
||||
|
||||
outputs[| 0].setValue(_data);
|
||||
network_trigger = true;
|
||||
|
@ -77,6 +96,10 @@ function Node_Websocket_Receiver(_x, _y, _group = noone) : Node(_x, _y, _group)
|
|||
} #endregion
|
||||
|
||||
static step = function() { #region
|
||||
var _mode = getInputData(2);
|
||||
|
||||
inputs[| 3].setVisible(_mode == 0);
|
||||
|
||||
if(network_trigger == 1) {
|
||||
outputs[| 1].setValue(1);
|
||||
network_trigger = -1;
|
||||
|
@ -88,10 +111,7 @@ function Node_Websocket_Receiver(_x, _y, _group = noone) : Node(_x, _y, _group)
|
|||
|
||||
static update = function(frame = CURRENT_FRAME) { #region
|
||||
if(CLONING) return;
|
||||
var _port = getInputData(0);
|
||||
|
||||
if(port != _port)
|
||||
setPort(_port);
|
||||
setPort();
|
||||
} #endregion
|
||||
|
||||
static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) { #region
|
||||
|
|
|
@ -60,12 +60,7 @@ function Node_Websocket_Sender(_x, _y, _group = noone) : Node(_x, _y, _group) co
|
|||
//print($"Connecting to {newUrl}:{newPort} complete");
|
||||
} #endregion
|
||||
|
||||
insp1UpdateTooltip = __txt("Resend");
|
||||
insp1UpdateIcon = [ THEME.refresh_icon, 1, COLORS._main_value_positive ];
|
||||
|
||||
static onInspector1Update = function() { #region
|
||||
triggerRender();
|
||||
} #endregion
|
||||
setInspector(1, __txt("Resend"), [ THEME.refresh_icon, 1, COLORS._main_value_positive ], function() { triggerRender(); });
|
||||
|
||||
static sendCall = function(ID, params) {
|
||||
var network = ds_map_try_get(NETWORK_CLIENTS, ID, noone);
|
||||
|
|
|
@ -22,8 +22,9 @@ function ExpCreateFile(path) {
|
|||
|
||||
function ExpFile(path) constructor {
|
||||
self.path = string_trim(path, [ "/", "\\" ]);
|
||||
name = filename_name_only(path);
|
||||
ext = string_lower(filename_ext(path));
|
||||
name = filename_name_only(path);
|
||||
ext = string_lower(filename_ext(path));
|
||||
parent = noone;
|
||||
|
||||
load_thumb = false;
|
||||
thumbnail = noone;
|
||||
|
@ -86,8 +87,11 @@ function ExpDir(path) : ExpFile(path) constructor {
|
|||
var f = file_find_first(path + "\\*", fa_directory);
|
||||
while (f != "") {
|
||||
var _fp = $"{path}\\{f}";
|
||||
if(directory_exists(_fp))
|
||||
array_push(directories, ExpCreateFile(_fp));
|
||||
if(directory_exists(_fp)) {
|
||||
var _fileObj = ExpCreateFile(_fp);
|
||||
_fileObj.parent = self;
|
||||
array_push(directories, _fileObj);
|
||||
}
|
||||
f = file_find_next();
|
||||
}
|
||||
|
||||
|
@ -95,8 +99,11 @@ function ExpDir(path) : ExpFile(path) constructor {
|
|||
var f = file_find_first(path + "\\*", fa_none);
|
||||
while (f != "") {
|
||||
var _fp = $"{path}\\{f}";
|
||||
if(file_exists(_fp) && !directory_exists(_fp))
|
||||
array_push(files, ExpCreateFile(_fp));
|
||||
if(file_exists(_fp) && !directory_exists(_fp)) {
|
||||
var _fileObj = ExpCreateFile(_fp);
|
||||
_fileObj.parent = self;
|
||||
array_push(files, _fileObj);
|
||||
}
|
||||
f = file_find_next();
|
||||
}
|
||||
|
||||
|
@ -174,6 +181,8 @@ function Panel_File_Explorer() : PanelContent() constructor {
|
|||
padding = ui(8);
|
||||
top_bar = ui(44);
|
||||
|
||||
grid_size = ui(64);
|
||||
|
||||
tb_root = new textBox(TEXTBOX_INPUT.text, function(val) {
|
||||
setRoot(val);
|
||||
});
|
||||
|
@ -214,6 +223,8 @@ function Panel_File_Explorer() : PanelContent() constructor {
|
|||
];
|
||||
|
||||
menu_file_project = [ menuItem("Open", function() { LOAD_AT(__menu_file_selecting.path); }), ];
|
||||
|
||||
menu_general = [ menuItem("Refresh", function() { if(rootFile) rootFile.getContent() }), ];
|
||||
#endregion
|
||||
|
||||
function onFocusBegin() { PANEL_FILE = self; }
|
||||
|
@ -238,8 +249,28 @@ function Panel_File_Explorer() : PanelContent() constructor {
|
|||
frame_drag_my = _m[1];
|
||||
|
||||
} else {
|
||||
if(!array_exists(file_selectings, file_hovering))
|
||||
if(key_mod_press(SHIFT)) {
|
||||
if(!array_empty(file_selectings)) {
|
||||
var _frm = file_selectings[array_length(file_selectings) - 1];
|
||||
var _to = file_hovering;
|
||||
|
||||
if(is_instanceof(_frm, ExpFile) && is_instanceof(_to, ExpFile) && _frm.parent && _frm.parent == _to.parent) {
|
||||
var _par = _frm.parent;
|
||||
var _ifrm = array_find(_par.files, _frm);
|
||||
var _ito = array_find(_par.files, _to);
|
||||
|
||||
file_selectings = array_create(abs(_ifrm - _ito) + 1);
|
||||
var _i = min(_ifrm, _ito);
|
||||
var _j = max(_ifrm, _ito);
|
||||
var _ind = 0;
|
||||
|
||||
for(; _i <= _j; _i++) file_selectings[_ind++] = _par.files[_i];
|
||||
}
|
||||
}
|
||||
|
||||
} else if(!array_exists(file_selectings, file_hovering))
|
||||
file_selectings = [ file_hovering ];
|
||||
|
||||
path_dragging = -1;
|
||||
file_dragging = true;
|
||||
file_drag_mx = mouse_mx;
|
||||
|
@ -249,6 +280,11 @@ function Panel_File_Explorer() : PanelContent() constructor {
|
|||
|
||||
if(mouse_release(mb_left)) frame_dragging = false;
|
||||
|
||||
if(pFOCUS && mouse_press(mb_right)) {
|
||||
if(file_hovering == noone || is_instanceof(file_hovering, ExpDir))
|
||||
menuCall("",,, menu_general);
|
||||
}
|
||||
|
||||
if(file_dragging) {
|
||||
if(path_dragging == -1 && point_distance(file_drag_mx, file_drag_my, mouse_mx, mouse_my) > 8) {
|
||||
path_dragging = [];
|
||||
|
@ -292,6 +328,11 @@ function Panel_File_Explorer() : PanelContent() constructor {
|
|||
}
|
||||
}
|
||||
|
||||
if(view_mode == FILE_EXPLORER_VIEW.grid && pHOVER && key_mod_press(CTRL)) {
|
||||
if(mouse_wheel_down()) grid_size = clamp(grid_size - ui(8), ui(32), ui(128));
|
||||
if(mouse_wheel_up()) grid_size = clamp(grid_size + ui(8), ui(32), ui(128));
|
||||
}
|
||||
|
||||
return _h;
|
||||
|
||||
} );
|
||||
|
@ -466,8 +507,8 @@ function Panel_File_Explorer() : PanelContent() constructor {
|
|||
}
|
||||
|
||||
} else if(view_mode == FILE_EXPLORER_VIEW.grid) {
|
||||
var _grid_width = ui(80);
|
||||
var _grid_height = ui(64);
|
||||
var _grid_width = grid_size + 1.25;
|
||||
var _grid_height = grid_size;
|
||||
var _grid_spac = ui(4);
|
||||
var _title_heigh = ui(24);
|
||||
draw_set_text(f_p3, fa_center, fa_bottom, COLORS._main_text);
|
||||
|
|
|
@ -5,7 +5,7 @@ function Panel_Palette() : PanelContent() constructor {
|
|||
w = ui(320);
|
||||
h = ui(480);
|
||||
|
||||
view_mode = 0;
|
||||
grid_size = ui(16);
|
||||
|
||||
color_dragging = noone;
|
||||
|
||||
|
@ -17,16 +17,16 @@ function Panel_Palette() : PanelContent() constructor {
|
|||
draw_clear_alpha(COLORS.panel_bg_clear, 0);
|
||||
var ww = sp_palettes.surface_w;
|
||||
var hh = ui(28);
|
||||
var _gs = ui(24);
|
||||
switch(view_mode) {
|
||||
case 0 : _gs = ui(24); break;
|
||||
case 1 : _gs = ui(32); break;
|
||||
case 2 : _gs = ui(16); break;
|
||||
}
|
||||
var _gs = grid_size;
|
||||
var _height;
|
||||
var yy = _y;
|
||||
var cur = CURRENT_COLOR;
|
||||
|
||||
if(pHOVER && key_mod_press(CTRL)) {
|
||||
if(mouse_wheel_down()) grid_size = clamp(grid_size - ui(4), ui(8), ui(32));
|
||||
if(mouse_wheel_up()) grid_size = clamp(grid_size + ui(4), ui(8), ui(32));
|
||||
}
|
||||
|
||||
for(var i = 0; i < array_length(PALETTES); i++) {
|
||||
var preset = PALETTES[i];
|
||||
var pre_amo = array_length(preset.palette);
|
||||
|
@ -80,9 +80,6 @@ function Panel_Palette() : PanelContent() constructor {
|
|||
menuItem(__txt("Refresh"), function() {
|
||||
__initPalette();
|
||||
}),
|
||||
menuItem(__txtx("palette_change_preview_size", "Change preview size"), function() {
|
||||
view_mode = (view_mode + 1) % 3;
|
||||
}),
|
||||
-1,
|
||||
menuItem(__txtx("palette_editor_set_default", "Set as default"), function() {
|
||||
PROJECT.setPalette(array_clone(hovering.palette));
|
||||
|
|
|
@ -61,7 +61,7 @@ function scrollPane(_w, _h, ondraw) : widget() constructor {
|
|||
scroll_y = round(scroll_y_raw);
|
||||
draw_surface_safe(surface, x, y);
|
||||
|
||||
if(hover && !scroll_lock && !key_mod_press(SHIFT)) {
|
||||
if(hover && !scroll_lock && !key_mod_press(SHIFT) && !key_mod_press(CTRL)) {
|
||||
if(mouse_wheel_down()) scroll_y_to -= scroll_step * SCROLL_SPEED;
|
||||
if(mouse_wheel_up()) scroll_y_to += scroll_step * SCROLL_SPEED;
|
||||
}
|
||||
|
|
|
@ -169,7 +169,6 @@ function shader_set_palette(pal, pal_uni = "palette", amo_uni = "paletteAmount",
|
|||
|
||||
var intp = attributes.interpolate;
|
||||
|
||||
gpu_set_tex_filter(intp);
|
||||
shader_set_uniform_i(shader_get_uniform(shader, "interpolation"), intp);
|
||||
shader_set_uniform_i(shader_get_uniform(shader, "sampleMode"), attributes.oversample);
|
||||
}
|
||||
|
@ -191,7 +190,6 @@ function shader_set_palette(pal, pal_uni = "palette", amo_uni = "paletteAmount",
|
|||
|
||||
var intp = attributes.interpolate;
|
||||
|
||||
// gpu_set_tex_filter(intp);
|
||||
shader_set_i("interpolation", intp);
|
||||
shader_set_f("sampleDimension", _dim == noone? surface_get_dimension(surface) : _dim);
|
||||
shader_set_i("sampleMode", attributes.oversample);
|
||||
|
@ -225,6 +223,8 @@ function shader_set_palette(pal, pal_uni = "palette", amo_uni = "paletteAmount",
|
|||
function surface_reset_shader() {
|
||||
if(!__surface_set) return;
|
||||
|
||||
shader_set_i("interpolation", 0);
|
||||
|
||||
BLEND_NORMAL;
|
||||
surface_reset_target();
|
||||
gpu_set_tex_filter(false);
|
||||
|
|
|
@ -11,6 +11,9 @@ uniform int useMap;
|
|||
uniform vec2 dimension;
|
||||
uniform float ditherSize;
|
||||
uniform float dither[64];
|
||||
uniform float seed;
|
||||
|
||||
float random (in vec2 st, float seed) { return fract(sin(dot(st.xy, vec2(1892.9898, 78.23453))) * (seed + 437.54123)); }
|
||||
|
||||
void main() {
|
||||
vec4 c = texture2D( gm_BaseTexture, v_vTexcoord );
|
||||
|
@ -28,13 +31,18 @@ void main() {
|
|||
float row = mod(pos.y, ditherSize);
|
||||
|
||||
val = dither[int(row * ditherSize + col)] / (ditherSize * ditherSize - 1.);
|
||||
} else {
|
||||
|
||||
} else if(useMap == 1) {
|
||||
float col = mod(pos.x, mapDimension.x);
|
||||
float row = mod(pos.y, mapDimension.y);
|
||||
vec4 map_data = texture2D( map, vec2(col, row) / mapDimension );
|
||||
|
||||
val = dot(map_data.rgb, vec3(0.2126, 0.7152, 0.0722));
|
||||
}
|
||||
|
||||
} else if(useMap == 2) {
|
||||
val = random(v_vTexcoord, seed);
|
||||
|
||||
}
|
||||
|
||||
c.a = c.a > val? 1. : 0.;
|
||||
|
||||
|
|
|
@ -17,38 +17,43 @@ uniform float dither[64];
|
|||
uniform vec2 dimension;
|
||||
uniform vec4 palette[32];
|
||||
uniform int keys;
|
||||
uniform float seed;
|
||||
|
||||
vec3 rgb2xyz( vec3 c ) { #region
|
||||
vec3 tmp;
|
||||
tmp.x = ( c.r > 0.04045 ) ? pow( ( c.r + 0.055 ) / 1.055, 2.4 ) : c.r / 12.92;
|
||||
tmp.y = ( c.g > 0.04045 ) ? pow( ( c.g + 0.055 ) / 1.055, 2.4 ) : c.g / 12.92,
|
||||
tmp.z = ( c.b > 0.04045 ) ? pow( ( c.b + 0.055 ) / 1.055, 2.4 ) : c.b / 12.92;
|
||||
return 100.0 * tmp *
|
||||
mat3( 0.4124, 0.3576, 0.1805,
|
||||
0.2126, 0.7152, 0.0722,
|
||||
0.0193, 0.1192, 0.9505 );
|
||||
} #endregion
|
||||
float random (in vec2 st, float seed) { return fract(sin(dot(st.xy, vec2(1892.9898, 78.23453))) * (seed + 437.54123)); }
|
||||
|
||||
vec3 xyz2lab( vec3 c ) { #region
|
||||
vec3 n = c / vec3( 95.047, 100, 108.883 );
|
||||
vec3 v;
|
||||
v.x = ( n.x > 0.008856 ) ? pow( n.x, 1.0 / 3.0 ) : ( 7.787 * n.x ) + ( 16.0 / 116.0 );
|
||||
v.y = ( n.y > 0.008856 ) ? pow( n.y, 1.0 / 3.0 ) : ( 7.787 * n.y ) + ( 16.0 / 116.0 );
|
||||
v.z = ( n.z > 0.008856 ) ? pow( n.z, 1.0 / 3.0 ) : ( 7.787 * n.z ) + ( 16.0 / 116.0 );
|
||||
return vec3(( 116.0 * v.y ) - 16.0, 500.0 * ( v.x - v.y ), 200.0 * ( v.y - v.z ));
|
||||
} #endregion
|
||||
#region ============================== COLOR SPACES ==============================
|
||||
vec3 rgb2xyz( vec3 c ) { #region
|
||||
vec3 tmp;
|
||||
tmp.x = ( c.r > 0.04045 ) ? pow( ( c.r + 0.055 ) / 1.055, 2.4 ) : c.r / 12.92;
|
||||
tmp.y = ( c.g > 0.04045 ) ? pow( ( c.g + 0.055 ) / 1.055, 2.4 ) : c.g / 12.92,
|
||||
tmp.z = ( c.b > 0.04045 ) ? pow( ( c.b + 0.055 ) / 1.055, 2.4 ) : c.b / 12.92;
|
||||
return 100.0 * tmp *
|
||||
mat3( 0.4124, 0.3576, 0.1805,
|
||||
0.2126, 0.7152, 0.0722,
|
||||
0.0193, 0.1192, 0.9505 );
|
||||
} #endregion
|
||||
|
||||
vec3 rgb2lab(vec3 c) { #region
|
||||
vec3 lab = xyz2lab( rgb2xyz( c ) );
|
||||
return vec3( lab.x / 100.0, 0.5 + 0.5 * ( lab.y / 127.0 ), 0.5 + 0.5 * ( lab.z / 127.0 ));
|
||||
} #endregion
|
||||
vec3 xyz2lab( vec3 c ) { #region
|
||||
vec3 n = c / vec3( 95.047, 100, 108.883 );
|
||||
vec3 v;
|
||||
v.x = ( n.x > 0.008856 ) ? pow( n.x, 1.0 / 3.0 ) : ( 7.787 * n.x ) + ( 16.0 / 116.0 );
|
||||
v.y = ( n.y > 0.008856 ) ? pow( n.y, 1.0 / 3.0 ) : ( 7.787 * n.y ) + ( 16.0 / 116.0 );
|
||||
v.z = ( n.z > 0.008856 ) ? pow( n.z, 1.0 / 3.0 ) : ( 7.787 * n.z ) + ( 16.0 / 116.0 );
|
||||
return vec3(( 116.0 * v.y ) - 16.0, 500.0 * ( v.x - v.y ), 200.0 * ( v.y - v.z ));
|
||||
} #endregion
|
||||
|
||||
float colorDifferent(in vec4 c1, in vec4 c2) { #region
|
||||
vec3 lab1 = rgb2lab(c1.rgb);
|
||||
vec3 lab2 = rgb2lab(c2.rgb);
|
||||
vec3 rgb2lab(vec3 c) { #region
|
||||
vec3 lab = xyz2lab( rgb2xyz( c ) );
|
||||
return vec3( lab.x / 100.0, 0.5 + 0.5 * ( lab.y / 127.0 ), 0.5 + 0.5 * ( lab.z / 127.0 ));
|
||||
} #endregion
|
||||
|
||||
float colorDifferent(in vec4 c1, in vec4 c2) { #region
|
||||
vec3 lab1 = rgb2lab(c1.rgb);
|
||||
vec3 lab2 = rgb2lab(c2.rgb);
|
||||
|
||||
return length(lab1 - lab2);
|
||||
} #endregion
|
||||
return length(lab1 - lab2);
|
||||
} #endregion
|
||||
#endregion
|
||||
|
||||
void main() { #region
|
||||
vec4 _col = v_vColour * texture2D( gm_BaseTexture, v_vTexcoord );
|
||||
|
@ -61,7 +66,7 @@ void main() { #region
|
|||
|
||||
for(int i = 0; i < keys; i++) {
|
||||
vec4 p_col = palette[i];
|
||||
float dif = colorDifferent(p_col, _col);
|
||||
float dif = colorDifferent(p_col, _col);
|
||||
|
||||
if(dif <= 0.001) {
|
||||
exactColor = true;
|
||||
|
@ -105,21 +110,25 @@ void main() { #region
|
|||
|
||||
float ditherVal = dither[int(row * ditherSize + col)] / (ditherSize * ditherSize - 1.);
|
||||
|
||||
if(rat <= 1. / (ditherSize * ditherSize) || rat < ditherVal)
|
||||
if(rat < ditherVal)
|
||||
gl_FragColor = col1;
|
||||
else
|
||||
gl_FragColor = col2;
|
||||
} else {
|
||||
|
||||
} else if(useMap == 1) {
|
||||
float col = pixelPos.x - floor(pixelPos.x / mapDimension.x) * mapDimension.x;
|
||||
float row = pixelPos.y - floor(pixelPos.y / mapDimension.y) * mapDimension.y;
|
||||
vec4 map_data = texture2D( map, vec2(col, row) / mapDimension );
|
||||
|
||||
float ditherVal = dot(map_data.rgb, vec3(0.2126, 0.7152, 0.0722));
|
||||
|
||||
if(rat <= 1. / (ditherSize * ditherSize) || rat < ditherVal)
|
||||
if(rat < ditherVal)
|
||||
gl_FragColor = col1;
|
||||
else
|
||||
gl_FragColor = col2;
|
||||
|
||||
} else if(useMap == 2) {
|
||||
gl_FragColor = rat < random(v_vTexcoord, seed)? col1 : col2;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
"%Name":"sh_dither",
|
||||
"name":"sh_dither",
|
||||
"parent":{
|
||||
"name":"filter",
|
||||
"path":"folders/shader/filter.yy",
|
||||
"name":"dither",
|
||||
"path":"folders/shader/filter/dither.yy",
|
||||
},
|
||||
"resourceType":"GMShader",
|
||||
"resourceVersion":"2.0",
|
||||
|
|
25
shaders/sh_dither_screen/sh_dither_screen.fsh
Normal file
25
shaders/sh_dither_screen/sh_dither_screen.fsh
Normal file
|
@ -0,0 +1,25 @@
|
|||
// Ditherimg algorithm from hornet,
|
||||
// Straight rip off from: https://www.shadertoy.com/view/MslGR8
|
||||
|
||||
varying vec2 v_vTexcoord;
|
||||
varying vec4 v_vColour;
|
||||
|
||||
uniform vec2 dimension;
|
||||
|
||||
vec3 ScreenSpaceDither( vec2 vScreenPos ) {
|
||||
vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), vScreenPos.xy ) );
|
||||
vDither.rgb = fract( vDither.rgb / vec3( 103.0, 71.0, 97.0 ) ) - vec3(0.5);
|
||||
|
||||
return vDither.rgb / 255.0 * 0.375;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 px = v_vTexcoord * dimension;
|
||||
|
||||
vec4 c = texture2D( gm_BaseTexture, v_vTexcoord );
|
||||
vec3 r = ScreenSpaceDither(px);
|
||||
|
||||
c.rgb += r;
|
||||
|
||||
gl_FragColor = c;
|
||||
}
|
19
shaders/sh_dither_screen/sh_dither_screen.vsh
Normal file
19
shaders/sh_dither_screen/sh_dither_screen.vsh
Normal file
|
@ -0,0 +1,19 @@
|
|||
//
|
||||
// Simple passthrough vertex shader
|
||||
//
|
||||
attribute vec3 in_Position; // (x,y,z)
|
||||
//attribute vec3 in_Normal; // (x,y,z) unused in this shader.
|
||||
attribute vec4 in_Colour; // (r,g,b,a)
|
||||
attribute vec2 in_TextureCoord; // (u,v)
|
||||
|
||||
varying vec2 v_vTexcoord;
|
||||
varying vec4 v_vColour;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 object_space_pos = vec4( in_Position.x, in_Position.y, in_Position.z, 1.0);
|
||||
gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * object_space_pos;
|
||||
|
||||
v_vColour = in_Colour;
|
||||
v_vTexcoord = in_TextureCoord;
|
||||
}
|
12
shaders/sh_dither_screen/sh_dither_screen.yy
Normal file
12
shaders/sh_dither_screen/sh_dither_screen.yy
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"$GMShader":"",
|
||||
"%Name":"sh_dither_screen",
|
||||
"name":"sh_dither_screen",
|
||||
"parent":{
|
||||
"name":"dither",
|
||||
"path":"folders/shader/filter/dither.yy",
|
||||
},
|
||||
"resourceType":"GMShader",
|
||||
"resourceVersion":"2.0",
|
||||
"type":1,
|
||||
}
|
|
@ -18,9 +18,7 @@ vec3 hsv2rgb(vec3 c) {
|
|||
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
||||
}
|
||||
|
||||
float random (in vec2 st, float seed) {
|
||||
return fract(sin(dot(st.xy + seed, vec2(1892.9898, 78.23453))) * 437.54123);
|
||||
}
|
||||
float random (in vec2 st, float seed) { return fract(sin(dot(st.xy + seed, vec2(1892.9898, 78.23453))) * 437.54123); }
|
||||
|
||||
float frandom (in vec2 st) {
|
||||
float n0 = random(st, floor(seed) / 5000.);
|
||||
|
|
Loading…
Reference in a new issue