path builder, file exp, dither noise

This commit is contained in:
Tanasart 2024-05-18 18:46:01 +07:00
parent 58ef98f8a8
commit a0a1941159
22 changed files with 388 additions and 198 deletions

View file

@ -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",},

View file

@ -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.

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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));

View file

@ -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];

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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);

View file

@ -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));

View file

@ -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;
}

View file

@ -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);

View file

@ -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.;

View file

@ -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;
}
}

View file

@ -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",

View 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;
}

View 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;
}

View 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,
}

View file

@ -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.);