Pixel-Composer/scripts/node_camera/node_camera.gml

224 lines
7.4 KiB
Plaintext
Raw Normal View History

2023-02-28 09:43:01 +01:00
function Node_Camera(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constructor {
2022-12-16 09:18:09 +01:00
name = "Camera";
preview_alpha = 0.5;
2023-01-17 08:11:55 +01:00
shader = sh_camera;
2023-01-25 06:49:00 +01:00
uni_backg = shader_get_sampler_index(shader, "backg");
2023-01-17 08:11:55 +01:00
uni_scene = shader_get_sampler_index(shader, "scene");
uni_dim_scn = shader_get_uniform(shader, "scnDimension");
uni_dim_cam = shader_get_uniform(shader, "camDimension");
uni_pos = shader_get_uniform(shader, "position");
uni_zom = shader_get_uniform(shader, "zoom");
uni_sam_mod = shader_get_uniform(shader, "sampleMode");
uni_blur = shader_get_uniform(shader, "blur");
2023-02-28 09:43:01 +01:00
uni_fix_bg = shader_get_uniform(shader, "fixBG");
2023-01-17 08:11:55 +01:00
2023-02-14 05:32:32 +01:00
inputs[| 0] = nodeValue("Background", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, 0);
2023-07-11 14:18:23 +02:00
inputs[| 1] = nodeValue("Focus area", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, [ 0, 0, 16, 16, AREA_SHAPE.rectangle ])
2023-01-17 08:11:55 +01:00
.setDisplay(VALUE_DISPLAY.area, function() { return getDimension(0); });
2023-02-14 05:32:32 +01:00
inputs[| 2] = nodeValue("Zoom", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 1)
2023-01-17 08:11:55 +01:00
.setDisplay(VALUE_DISPLAY.slider, [ 0.01, 4, 0.01 ]);
2023-02-14 05:32:32 +01:00
inputs[| 3] = nodeValue("Oversample mode", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0, "How to deal with pixel outside the surface.\n - Empty: Use empty pixel\n - Clamp: Repeat edge pixel\n - Repeat: Repeat texture.")
2023-07-11 14:18:23 +02:00
.setDisplay(VALUE_DISPLAY.enum_scroll, [ "Empty", "Repeat" ]);
2022-12-16 09:18:09 +01:00
2023-02-28 09:43:01 +01:00
inputs[| 4] = nodeValue("Fix background", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false);
2023-02-14 05:32:32 +01:00
outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone);
2022-12-16 09:18:09 +01:00
2023-01-17 08:11:55 +01:00
input_display_list = [
2023-07-11 14:18:23 +02:00
["Background", true], 0, 4, 3,
["Camera", false], 1, 2,
["Elements", true],
2023-01-17 08:11:55 +01:00
];
2023-03-19 09:17:39 +01:00
attribute_surface_depth();
2023-07-11 14:18:23 +02:00
2023-01-17 08:11:55 +01:00
input_display_len = array_length(input_display_list);
2023-07-11 14:18:23 +02:00
input_fix_len = ds_list_size(inputs);
data_length = 3;
temp_surface = [ noone, noone ];
2023-01-17 08:11:55 +01:00
function createNewInput() {
var index = ds_list_size(inputs);
var _s = floor((index - input_fix_len) / data_length);
2023-07-11 14:18:23 +02:00
inputs[| index + 0] = nodeValue($"Element {_s}", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, 0);
2023-01-17 08:11:55 +01:00
2023-07-11 14:18:23 +02:00
inputs[| index + 1] = nodeValue($"Parallax {_s}", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0, 0, 0 ] )
2023-01-17 08:11:55 +01:00
.setDisplay(VALUE_DISPLAY.vector)
.setUnitRef(function(index) { return getDimension(index); });
2023-07-11 14:18:23 +02:00
inputs[| index + 2] = nodeValue($"Oversample {_s}", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0)
.setDisplay(VALUE_DISPLAY.enum_scroll, [ "Empty", "Repeat" ]);
array_append(input_display_list, [ index + 0, index + 1, index + 2 ]);
2023-01-17 08:11:55 +01:00
}
if(!LOADING && !APPENDING) createNewInput();
static refreshDynamicInput = function() {
var _in = ds_list_create();
for( var i = 0; i < input_fix_len; i++ )
ds_list_add(_in, inputs[| i]);
array_resize(input_display_list, input_display_len);
for( var i = input_fix_len; i < ds_list_size(inputs); i += data_length ) {
if(inputs[| i].value_from) {
ds_list_add(_in, inputs[| i + 0]);
ds_list_add(_in, inputs[| i + 1]);
2023-07-11 14:18:23 +02:00
ds_list_add(_in, inputs[| i + 2]);
2023-01-17 08:11:55 +01:00
array_push(input_display_list, i + 0);
array_push(input_display_list, i + 1);
2023-07-11 14:18:23 +02:00
array_push(input_display_list, i + 2);
2023-01-17 08:11:55 +01:00
} else {
delete inputs[| i + 0];
delete inputs[| i + 1];
2023-07-11 14:18:23 +02:00
delete inputs[| i + 2];
2023-01-17 08:11:55 +01:00
}
}
for( var i = 0; i < ds_list_size(_in); i++ )
_in[| i].index = i;
ds_list_destroy(inputs);
inputs = _in;
createNewInput();
}
static onValueFromUpdate = function(index) {
if(index < input_fix_len) return;
if(LOADING || APPENDING) return;
refreshDynamicInput();
}
2022-12-16 09:18:09 +01:00
static getPreviewValue = function() { return inputs[| 0]; }
2022-12-19 13:35:30 +01:00
static drawOverlay = function(active, _x, _y, _s, _mx, _my, _snx, _sny) {
2022-12-27 04:00:50 +01:00
if(array_length(current_data) == 0) return;
2022-12-16 09:18:09 +01:00
var _out = outputs[| 0].getValue();
var _area = current_data[1];
2023-01-17 08:11:55 +01:00
var _zoom = current_data[2];
2022-12-16 09:18:09 +01:00
2023-07-11 14:18:23 +02:00
var _cam_x = _x + (_area[0] - _area[2] * _zoom) * _s;
var _cam_y = _y + (_area[1] - _area[3] * _zoom) * _s;
2023-01-17 08:11:55 +01:00
2023-07-11 14:18:23 +02:00
draw_surface_ext_safe(_out, _cam_x, _cam_y, _s * _zoom, _s * _zoom);
2022-12-19 13:35:30 +01:00
inputs[| 1].drawOverlay(active, _x, _y, _s, _mx, _my, _snx, _sny);
2023-01-17 08:11:55 +01:00
draw_set_color(COLORS._main_accent);
2023-07-11 14:18:23 +02:00
var x0 = _cam_x;
var y0 = _cam_y;
2023-01-17 08:11:55 +01:00
var x1 = x0 + _area[2] * 2 * _zoom * _s;
var y1 = y0 + _area[3] * 2 * _zoom * _s;
draw_rectangle_dashed(x0, y0, x1, y1);
2022-12-16 09:18:09 +01:00
}
2023-01-01 02:06:02 +01:00
static process_data = function(_outSurf, _data, _output_index, _array_index) {
2023-02-14 05:32:32 +01:00
if(!is_surface(_data[0])) return;
2022-12-16 09:18:09 +01:00
var _area = _data[1];
2023-01-17 08:11:55 +01:00
var _zoom = _data[2];
2023-07-11 14:18:23 +02:00
var _samp = _data[3];
2023-02-28 09:43:01 +01:00
var _fix = _data[4];
2023-03-19 09:17:39 +01:00
var cDep = attrDepth();
2022-12-16 09:18:09 +01:00
2023-07-11 14:18:23 +02:00
var _cam_x = round(_area[0]);
var _cam_y = round(_area[1]);
var _cam_w = round(_area[2]);
var _cam_h = round(_area[3]);
var _surf_w = round(surface_valid_size(_cam_w * 2));
var _surf_h = round(surface_valid_size(_cam_h * 2));
var ppInd = 0;
_outSurf = surface_verify(_outSurf, _surf_w, _surf_h, cDep);
temp_surface[0] = surface_verify(temp_surface[0], _surf_w, _surf_h, cDep);
temp_surface[1] = surface_verify(temp_surface[1], _surf_w, _surf_h, cDep);
2023-01-25 06:49:00 +01:00
2023-02-28 09:43:01 +01:00
var amo = (ds_list_size(inputs) - input_fix_len) / data_length - 1;
2023-07-11 14:18:23 +02:00
surface_set_target(temp_surface[0]);
2023-03-19 09:17:39 +01:00
DRAW_CLEAR
2023-02-14 05:32:32 +01:00
BLEND_OVERRIDE;
2023-02-28 09:43:01 +01:00
if(amo <= 0) {
if(_fix) {
2023-03-19 09:17:39 +01:00
if(_samp) draw_surface_tiled_safe(_data[0], 0, 0);
else draw_surface_safe(_data[0], 0, 0);
2023-02-28 09:43:01 +01:00
} else {
2023-07-11 14:18:23 +02:00
var sx = _cam_x / _zoom - _cam_w;
var sy = _cam_y / _zoom - _cam_h;
2023-03-19 09:17:39 +01:00
if(_samp) draw_surface_tiled_ext_safe(_data[0], -sx, -sy, 1 / _zoom, 1 / _zoom, c_white, 1);
else draw_surface_ext_safe(_data[0], -sx, -sy, 1 / _zoom, 1 / _zoom, 0, c_white, 1);
2023-02-28 09:43:01 +01:00
}
} else {
2023-07-11 14:18:23 +02:00
var sx = _cam_x / _zoom - _cam_w;
var sy = _cam_y / _zoom - _cam_h;
2023-02-28 09:43:01 +01:00
2023-03-19 09:17:39 +01:00
if(_fix) draw_surface_safe(_data[0], 0, 0);
else draw_surface_tiled_ext_safe(_data[0], sx, sy, 1 / _zoom, 1 / _zoom, c_white, 1);
2023-02-28 09:43:01 +01:00
}
2023-02-14 05:32:32 +01:00
BLEND_NORMAL;
2023-01-25 06:49:00 +01:00
surface_reset_target();
2023-07-11 14:18:23 +02:00
surface_set_target(temp_surface[1]);
2023-03-19 09:17:39 +01:00
DRAW_CLEAR
2023-01-25 06:49:00 +01:00
surface_reset_target();
2022-12-16 09:18:09 +01:00
2023-01-17 08:11:55 +01:00
shader_set(shader);
2023-07-11 14:18:23 +02:00
shader_set_uniform_f(uni_dim_cam, _surf_w, _surf_h);
2023-01-25 06:49:00 +01:00
shader_set_uniform_f(uni_zom, _zoom);
for( var i = 0; i < amo; i++ ) {
ppInd = !ppInd;
2023-01-17 08:11:55 +01:00
2023-07-11 14:18:23 +02:00
surface_set_target(temp_surface[ppInd]);
2023-01-25 06:49:00 +01:00
var ind = input_fix_len + i * data_length;
2023-01-17 08:11:55 +01:00
2023-01-25 06:49:00 +01:00
var _surface = _data[ind];
2023-07-11 14:18:23 +02:00
var sz = _data[ind + 1][2];
var sx = _data[ind + 1][0] * sz * _cam_x;
var sy = _data[ind + 1][1] * sz * _cam_y;
var _samp = _data[ind + 2];
2023-01-25 06:49:00 +01:00
var _scnW = surface_get_width(_surface);
var _scnH = surface_get_height(_surface);
2023-07-11 14:18:23 +02:00
shader_set_uniform_i(uni_sam_mod, _samp);
2023-01-25 06:49:00 +01:00
shader_set_uniform_f(uni_dim_scn, _scnW, _scnH);
shader_set_uniform_f(uni_blur, sz);
2023-07-11 14:18:23 +02:00
shader_set_uniform_f(uni_pos, (_cam_x + sx) / _scnW, (_cam_y + sy) / _scnH);
2023-02-28 09:43:01 +01:00
shader_set_uniform_i(uni_fix_bg, !i && _fix);
2023-07-11 14:18:23 +02:00
texture_set_stage(uni_backg, surface_get_texture(temp_surface[!ppInd])); //prev surface
2023-02-28 09:43:01 +01:00
texture_set_stage(uni_scene, surface_get_texture(_surface)); //surface to draw
2023-07-11 14:18:23 +02:00
draw_sprite_ext(s_fx_pixel, 0, 0, 0, _surf_w, _surf_h, 0, c_white, 1);
2023-01-25 06:49:00 +01:00
surface_reset_target();
}
2023-01-17 08:11:55 +01:00
shader_reset();
2023-01-25 06:49:00 +01:00
surface_set_target(_outSurf);
2023-03-19 09:17:39 +01:00
DRAW_CLEAR
2023-02-14 05:32:32 +01:00
BLEND_OVERRIDE;
2023-07-11 14:18:23 +02:00
draw_surface_safe(temp_surface[ppInd], 0, 0);
2023-02-14 05:32:32 +01:00
BLEND_NORMAL;
2022-12-16 09:18:09 +01:00
surface_reset_target();
return _outSurf;
}
2023-01-17 08:11:55 +01:00
static postDeserialize = function() {
2023-06-13 14:42:06 +02:00
var _inputs = load_map.inputs;
2023-01-17 08:11:55 +01:00
2023-06-13 14:42:06 +02:00
for(var i = input_fix_len; i < array_length(_inputs); i += data_length)
2023-01-17 08:11:55 +01:00
createNewInput();
}
2022-12-16 09:18:09 +01:00
}