Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/space_node')
-rw-r--r--source/blender/editors/space_node/CMakeLists.txt2
-rw-r--r--source/blender/editors/space_node/drawnode.c782
-rw-r--r--source/blender/editors/space_node/node_add.c14
-rw-r--r--source/blender/editors/space_node/node_draw.c505
-rw-r--r--source/blender/editors/space_node/node_edit.c114
-rw-r--r--source/blender/editors/space_node/node_intern.h18
-rw-r--r--source/blender/editors/space_node/node_manipulators.c616
-rw-r--r--source/blender/editors/space_node/node_ops.c6
-rw-r--r--source/blender/editors/space_node/node_templates.c5
-rw-r--r--source/blender/editors/space_node/space_node.c98
10 files changed, 1379 insertions, 781 deletions
diff --git a/source/blender/editors/space_node/CMakeLists.txt b/source/blender/editors/space_node/CMakeLists.txt
index cde818333e4..77b1351435b 100644
--- a/source/blender/editors/space_node/CMakeLists.txt
+++ b/source/blender/editors/space_node/CMakeLists.txt
@@ -24,6 +24,7 @@ set(INC
../../blenkernel
../../blenlib
../../blentranslation
+ ../../depsgraph
../../imbuf
../../gpu
../../makesdna
@@ -47,6 +48,7 @@ set(SRC
node_draw.c
node_edit.c
node_group.c
+ node_manipulators.c
node_ops.c
node_relationships.c
node_select.c
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index ea8d4b36d3b..19e2ae9808a 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -50,9 +50,13 @@
#include "BLF_api.h"
#include "BLT_translation.h"
-#include "BIF_gl.h"
#include "BIF_glutil.h"
+#include "GPU_draw.h"
+#include "GPU_batch.h"
+#include "GPU_immediate.h"
+#include "GPU_matrix.h"
+
#include "RNA_access.h"
#include "RNA_define.h"
@@ -62,6 +66,7 @@
#include "WM_types.h"
#include "UI_resources.h"
+#include "UI_view2d.h"
#include "IMB_colormanagement.h"
#include "IMB_imbuf_types.h"
@@ -80,49 +85,6 @@ static void node_socket_button_label(bContext *UNUSED(C), uiLayout *layout, Poin
uiItemL(layout, text, 0);
}
-
-/* ****************** BASE DRAW FUNCTIONS FOR NEW OPERATOR NODES ***************** */
-
-#if 0 /* UNUSED */
-static void node_draw_socket_new(bNodeSocket *sock, float size)
-{
- float x = sock->locx, y = sock->locy;
-
- /* 16 values of sin function */
- static float si[16] = {
- 0.00000000f, 0.39435585f, 0.72479278f, 0.93775213f,
- 0.99871650f, 0.89780453f, 0.65137248f, 0.29936312f,
- -0.10116832f, -0.48530196f, -0.79077573f, -0.96807711f,
- -0.98846832f, -0.84864425f, -0.57126821f, -0.20129852f
- };
- /* 16 values of cos function */
- static float co[16] = {
- 1.00000000f, 0.91895781f, 0.68896691f, 0.34730525f,
- -0.05064916f, -0.44039415f, -0.75875812f, -0.95413925f,
- -0.99486932f, -0.87434661f, -0.61210598f, -0.25065253f,
- 0.15142777f, 0.52896401f, 0.82076344f, 0.97952994f,
- };
- int a;
-
- glColor3ub(180, 180, 180);
-
- glBegin(GL_POLYGON);
- for (a = 0; a < 16; a++)
- glVertex2f(x + size * si[a], y + size * co[a]);
- glEnd();
-
- glColor4ub(0, 0, 0, 150);
- glEnable(GL_BLEND);
- glEnable(GL_LINE_SMOOTH);
- glBegin(GL_LINE_LOOP);
- for (a = 0; a < 16; a++)
- glVertex2f(x + size * si[a], y + size * co[a]);
- glEnd();
- glDisable(GL_LINE_SMOOTH);
- glDisable(GL_BLEND);
-}
-#endif
-
/* ****************** BUTTON CALLBACKS FOR ALL TREES ***************** */
static void node_buts_value(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -392,6 +354,7 @@ static void node_draw_frame_label(bNodeTree *ntree, bNode *node, const float asp
const int font_size = data->label_size / aspect;
const float margin = (float)(NODE_DY / 4);
int label_height;
+ unsigned char color[3];
nodeLabel(ntree, node, label, sizeof(label));
@@ -400,7 +363,8 @@ static void node_draw_frame_label(bNodeTree *ntree, bNode *node, const float asp
BLF_size(fontid, MIN2(24, font_size), U.dpi); /* clamp otherwise it can suck up a LOT of memory */
/* title color */
- UI_ThemeColorBlendShade(TH_TEXT, color_id, 0.4f, 10);
+ UI_GetThemeColorBlendShade3ubv(TH_TEXT, color_id, 0.4f, 10, color);
+ BLF_color3ubv(fontid, color);
width = BLF_width(fontid, label, sizeof(label));
ascender = BLF_ascender(fontid);
@@ -465,7 +429,7 @@ static void node_draw_frame(const bContext *C, ARegion *ar, SpaceNode *snode,
{
rctf *rct = &node->totr;
int color_id = node_get_colorid(node);
- unsigned char color[4];
+ float color[4];
float alpha;
/* skip if out of view */
@@ -475,40 +439,32 @@ static void node_draw_frame(const bContext *C, ARegion *ar, SpaceNode *snode,
return;
}
- UI_GetThemeColor4ubv(TH_NODE_FRAME, color);
- alpha = (float)(color[3]) / 255.0f;
+ UI_GetThemeColor4fv(TH_NODE_FRAME, color);
+ alpha = color[3];
/* shadow */
node_draw_shadow(snode, node, BASIS_RAD, alpha);
/* body */
- if (node->flag & NODE_CUSTOM_COLOR)
- glColor4f(node->color[0], node->color[1], node->color[2], alpha);
+ if (node->flag & NODE_CUSTOM_COLOR) {
+ rgba_float_args_set(color, node->color[0], node->color[1], node->color[2], alpha);
+ }
else
- UI_ThemeColor4(TH_NODE_FRAME);
- glEnable(GL_BLEND);
+ UI_GetThemeColor4fv(TH_NODE_FRAME, color);
+
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox(rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD);
- glDisable(GL_BLEND);
+ UI_draw_roundbox_aa(true, rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD, color);
/* outline active and selected emphasis */
if (node->flag & SELECT) {
- glEnable(GL_BLEND);
- glEnable(GL_LINE_SMOOTH);
-
if (node->flag & NODE_ACTIVE)
- UI_ThemeColorShadeAlpha(TH_ACTIVE, 0, -40);
+ UI_GetThemeColorShadeAlpha4fv(TH_ACTIVE, 0, -40, color);
else
- UI_ThemeColorShadeAlpha(TH_SELECT, 0, -40);
- UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_gl_mode(GL_LINE_LOOP,
- rct->xmin, rct->ymin,
- rct->xmax, rct->ymax, BASIS_RAD);
-
- glDisable(GL_LINE_SMOOTH);
- glDisable(GL_BLEND);
+ UI_GetThemeColorShadeAlpha4fv(TH_SELECT, 0, -40, color);
+
+ UI_draw_roundbox_aa(false, rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD, color);
}
-
+
/* label */
node_draw_frame_label(ntree, node, snode->aspect);
@@ -580,15 +536,9 @@ static void node_draw_reroute_prepare(const bContext *UNUSED(C), bNodeTree *UNUS
static void node_draw_reroute(const bContext *C, ARegion *ar, SpaceNode *UNUSED(snode),
bNodeTree *ntree, bNode *node, bNodeInstanceKey UNUSED(key))
{
- bNodeSocket *sock;
char showname[128]; /* 128 used below */
rctf *rct = &node->totr;
-#if 0 /* UNUSED */
- float size = NODE_REROUTE_SIZE;
-#endif
- float socket_size = NODE_SOCKSIZE;
-
/* skip if out of view */
if (node->totr.xmax < ar->v2d.cur.xmin || node->totr.xmin > ar->v2d.cur.xmax ||
node->totr.ymax < ar->v2d.cur.ymin || node->totr.ymin > ar->v2d.cur.ymax)
@@ -602,23 +552,26 @@ static void node_draw_reroute(const bContext *C, ARegion *ar, SpaceNode *UNUSED(
* selection state is indicated by socket outline below!
*/
#if 0
+ float size = NODE_REROUTE_SIZE;
+
/* body */
+ float debug_color[4];
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_ThemeColor4(TH_NODE);
- glEnable(GL_BLEND);
- UI_draw_roundbox(rct->xmin, rct->ymin, rct->xmax, rct->ymax, size);
- glDisable(GL_BLEND);
+ UI_GetThemeColor4fv(TH_NODE, debug_color);
+ UI_draw_roundbox_aa(true, rct->xmin, rct->ymin, rct->xmax, rct->ymax, size, debug_color);
/* outline active and selected emphasis */
if (node->flag & SELECT) {
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
/* using different shades of TH_TEXT_HI for the empasis, like triangle */
- if (node->flag & NODE_ACTIVE)
- UI_ThemeColorShadeAlpha(TH_TEXT_HI, 0, -40);
- else
- UI_ThemeColorShadeAlpha(TH_TEXT_HI, -20, -120);
- UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rct->xmin, rct->ymin, rct->xmax, rct->ymax, size);
+ if (node->flag & NODE_ACTIVE) {
+ UI_GetThemeColorShadeAlpha4fv(TH_TEXT_HI, 0, -40, debug_color);
+ }
+ else {
+ UI_GetThemeColorShadeAlpha4fv(TH_TEXT_HI, -20, -120, debug_color);
+ }
+ UI_draw_roundbox_4fv(false, rct->xmin, rct->ymin, rct->xmax, rct->ymax, size, debug_color);
glDisable(GL_LINE_SMOOTH);
glDisable(GL_BLEND);
@@ -637,9 +590,7 @@ static void node_draw_reroute(const bContext *C, ARegion *ar, SpaceNode *UNUSED(
/* only draw input socket. as they all are placed on the same position.
* highlight also if node itself is selected, since we don't display the node body separately!
*/
- for (sock = node->inputs.first; sock; sock = sock->next) {
- node_socket_draw(C, ntree, node, sock, socket_size, (sock->flag & SELECT) || (node->flag & SELECT));
- }
+ node_draw_sockets(&ar->v2d, C, ntree, node, false, node->flag & SELECT);
UI_block_end(C, node->block);
UI_block_draw(C, node->block);
@@ -728,21 +679,6 @@ static void node_buts_image_user(uiLayout *layout, bContext *C, PointerRNA *ptr,
}
}
-static void node_shader_buts_material(uiLayout *layout, bContext *C, PointerRNA *ptr)
-{
- bNode *node = ptr->data;
- uiLayout *col;
-
- uiTemplateID(layout, C, ptr, "material", "MATERIAL_OT_new", NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL);
-
- if (!node->id) return;
-
- col = uiLayoutColumn(layout, false);
- uiItemR(col, ptr, "use_diffuse", 0, NULL, ICON_NONE);
- uiItemR(col, ptr, "use_specular", 0, NULL, ICON_NONE);
- uiItemR(col, ptr, "invert_normal", 0, NULL, ICON_NONE);
-}
-
static void node_shader_buts_mapping(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayout *row, *col, *sub;
@@ -790,30 +726,6 @@ static void node_shader_buts_vect_transform(uiLayout *layout, bContext *UNUSED(C
uiItemR(layout, ptr, "convert_to", 0, "", ICON_NONE);
}
-static void node_shader_buts_geometry(uiLayout *layout, bContext *C, PointerRNA *ptr)
-{
- PointerRNA obptr = CTX_data_pointer_get(C, "active_object");
- uiLayout *col;
-
- col = uiLayoutColumn(layout, false);
-
- if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) {
- PointerRNA dataptr = RNA_pointer_get(&obptr, "data");
-
- uiItemPointerR(col, ptr, "uv_layer", &dataptr, "uv_textures", "", ICON_NONE);
- uiItemPointerR(col, ptr, "color_layer", &dataptr, "vertex_colors", "", ICON_NONE);
- }
- else {
- uiItemR(col, ptr, "uv_layer", 0, IFACE_("UV"), ICON_NONE);
- uiItemR(col, ptr, "color_layer", 0, IFACE_("VCol"), ICON_NONE);
- }
-}
-
-static void node_shader_buts_lamp(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "lamp_object", 0, IFACE_("Lamp Object"), ICON_NONE);
-}
-
static void node_shader_buts_attribute(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "attribute_name", 0, IFACE_("Name"), ICON_NONE);
@@ -1022,7 +934,7 @@ static void node_shader_buts_uvmap(uiLayout *layout, bContext *C, PointerRNA *pt
if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) {
PointerRNA dataptr = RNA_pointer_get(&obptr, "data");
- uiItemPointerR(layout, ptr, "uv_map", &dataptr, "uv_textures", "", ICON_NONE);
+ uiItemPointerR(layout, ptr, "uv_map", &dataptr, "uv_layers", "", ICON_NONE);
}
}
}
@@ -1041,7 +953,7 @@ static void node_shader_buts_normal_map(uiLayout *layout, bContext *C, PointerRN
if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) {
PointerRNA dataptr = RNA_pointer_get(&obptr, "data");
- uiItemPointerR(layout, ptr, "uv_map", &dataptr, "uv_textures", "", ICON_NONE);
+ uiItemPointerR(layout, ptr, "uv_map", &dataptr, "uv_layers", "", ICON_NONE);
}
else
uiItemR(layout, ptr, "uv_map", 0, "", 0);
@@ -1068,7 +980,7 @@ static void node_shader_buts_tangent(uiLayout *layout, bContext *C, PointerRNA *
if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) {
PointerRNA dataptr = RNA_pointer_get(&obptr, "data");
- uiItemPointerR(row, ptr, "uv_map", &dataptr, "uv_textures", "", ICON_NONE);
+ uiItemPointerR(row, ptr, "uv_map", &dataptr, "uv_layers", "", ICON_NONE);
}
else
uiItemR(row, ptr, "uv_map", 0, "", 0);
@@ -1172,13 +1084,6 @@ static void node_shader_buts_bevel(uiLayout *layout, bContext *UNUSED(C), Pointe
static void node_shader_set_butfunc(bNodeType *ntype)
{
switch (ntype->type) {
- case SH_NODE_MATERIAL:
- case SH_NODE_MATERIAL_EXT:
- ntype->draw_buttons = node_shader_buts_material;
- break;
- case SH_NODE_TEXTURE:
- ntype->draw_buttons = node_buts_texture;
- break;
case SH_NODE_NORMAL:
ntype->draw_buttons = node_buts_normal;
break;
@@ -1212,12 +1117,6 @@ static void node_shader_set_butfunc(bNodeType *ntype)
case SH_NODE_VECT_TRANSFORM:
ntype->draw_buttons = node_shader_buts_vect_transform;
break;
- case SH_NODE_GEOMETRY:
- ntype->draw_buttons = node_shader_buts_geometry;
- break;
- case SH_NODE_LAMP:
- ntype->draw_buttons = node_shader_buts_lamp;
- break;
case SH_NODE_ATTRIBUTE:
ntype->draw_buttons = node_shader_buts_attribute;
break;
@@ -1363,7 +1262,7 @@ static void node_composit_buts_image_ex(uiLayout *layout, bContext *C, PointerRN
uiTemplateImage(layout, C, ptr, "image", &iuserptr, 0, 1);
}
-static void node_composit_buts_renderlayers(uiLayout *layout, bContext *C, PointerRNA *ptr)
+static void node_composit_buts_viewlayers(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
bNode *node = ptr->data;
uiLayout *col, *row;
@@ -2261,14 +2160,21 @@ static void node_composit_backdrop_viewer(SpaceNode *snode, ImBuf *backdrop, bNo
const float cy = y + snode->zoom * backdropHeight * node->custom4;
const float cross_size = 12 * U.pixelsize;
- glColor3f(1.0, 1.0, 1.0);
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor3f(1.0f, 1.0f, 1.0f);
- glBegin(GL_LINES);
- glVertex2f(cx - cross_size, cy - cross_size);
- glVertex2f(cx + cross_size, cy + cross_size);
- glVertex2f(cx + cross_size, cy - cross_size);
- glVertex2f(cx - cross_size, cy + cross_size);
- glEnd();
+ immBegin(GWN_PRIM_LINES, 4);
+ immVertex2f(pos, cx - cross_size, cy - cross_size);
+ immVertex2f(pos, cx + cross_size, cy + cross_size);
+ immVertex2f(pos, cx + cross_size, cy - cross_size);
+ immVertex2f(pos, cx - cross_size, cy + cross_size);
+ immEnd();
+
+ immUnbindProgram();
}
}
@@ -2287,9 +2193,6 @@ static void node_composit_backdrop_boxmask(SpaceNode *snode, ImBuf *backdrop, bN
float cx, cy, x1, x2, x3, x4;
float y1, y2, y3, y4;
-
- glColor3f(1.0, 1.0, 1.0);
-
cx = x + snode->zoom * backdropWidth * boxmask->x;
cy = y + snode->zoom * backdropHeight * boxmask->y;
@@ -2302,12 +2205,21 @@ static void node_composit_backdrop_boxmask(SpaceNode *snode, ImBuf *backdrop, bN
y3 = cy - (-sine * -halveBoxWidth + cosine * -halveBoxHeight) * snode->zoom;
y4 = cy - (-sine * halveBoxWidth + cosine * -halveBoxHeight) * snode->zoom;
- glBegin(GL_LINE_LOOP);
- glVertex2f(x1, y1);
- glVertex2f(x2, y2);
- glVertex2f(x3, y3);
- glVertex2f(x4, y4);
- glEnd();
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor3f(1.0f, 1.0f, 1.0f);
+
+ immBegin(GWN_PRIM_LINE_LOOP, 4);
+ immVertex2f(pos, x1, y1);
+ immVertex2f(pos, x2, y2);
+ immVertex2f(pos, x3, y3);
+ immVertex2f(pos, x4, y4);
+ immEnd();
+
+ immUnbindProgram();
}
static void node_composit_backdrop_ellipsemask(SpaceNode *snode, ImBuf *backdrop, bNode *node, int x, int y)
@@ -2325,9 +2237,6 @@ static void node_composit_backdrop_ellipsemask(SpaceNode *snode, ImBuf *backdrop
float cx, cy, x1, x2, x3, x4;
float y1, y2, y3, y4;
-
- glColor3f(1.0, 1.0, 1.0);
-
cx = x + snode->zoom * backdropWidth * ellipsemask->x;
cy = y + snode->zoom * backdropHeight * ellipsemask->y;
@@ -2340,13 +2249,21 @@ static void node_composit_backdrop_ellipsemask(SpaceNode *snode, ImBuf *backdrop
y3 = cy - (-sine * -halveBoxWidth + cosine * -halveBoxHeight) * snode->zoom;
y4 = cy - (-sine * halveBoxWidth + cosine * -halveBoxHeight) * snode->zoom;
- glBegin(GL_LINE_LOOP);
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- glVertex2f(x1, y1);
- glVertex2f(x2, y2);
- glVertex2f(x3, y3);
- glVertex2f(x4, y4);
- glEnd();
+ immUniformColor3f(1.0f, 1.0f, 1.0f);
+
+ immBegin(GWN_PRIM_LINE_LOOP, 4);
+ immVertex2f(pos, x1, y1);
+ immVertex2f(pos, x2, y2);
+ immVertex2f(pos, x3, y3);
+ immVertex2f(pos, x4, y4);
+ immEnd();
+
+ immUnbindProgram();
}
static void node_composit_buts_ellipsemask(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -2546,7 +2463,7 @@ static void node_composit_set_butfunc(bNodeType *ntype)
ntype->draw_buttons_ex = node_composit_buts_image_ex;
break;
case CMP_NODE_R_LAYERS:
- ntype->draw_buttons = node_composit_buts_renderlayers;
+ ntype->draw_buttons = node_composit_buts_viewlayers;
break;
case CMP_NODE_NORMAL:
ntype->draw_buttons = node_buts_normal;
@@ -3235,6 +3152,7 @@ void ED_init_node_socket_type_virtual(bNodeSocketType *stype)
void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeInstanceKey parent_key)
{
bNodeInstanceKey active_viewer_key = (snode->nodetree ? snode->nodetree->active_viewer_key : NODE_INSTANCE_KEY_NONE);
+ float shuffle[4] = {0.0f, 0.0f, 0.0f, 0.0f};
Image *ima;
void *lock;
ImBuf *ibuf;
@@ -3249,15 +3167,11 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode, b
ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
if (ibuf) {
float x, y;
-
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
-
+
+ gpuPushProjectionMatrix();
+ gpuPushMatrix();
+
/* somehow the offset has to be calculated inverse */
-
- glaDefine2DArea(&ar->winrct);
wmOrtho2_region_pixelspace(ar);
x = (ar->winx - snode->zoom * ibuf->x) / 2 + snode->xof;
@@ -3267,60 +3181,37 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode, b
unsigned char *display_buffer = NULL;
void *cache_handle = NULL;
- if (snode->flag & (SNODE_SHOW_R | SNODE_SHOW_G | SNODE_SHOW_B)) {
- int ofs;
+ if (snode->flag & (SNODE_SHOW_R | SNODE_SHOW_G | SNODE_SHOW_B | SNODE_SHOW_ALPHA)) {
display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
-
-#ifdef __BIG_ENDIAN__
- if (snode->flag & SNODE_SHOW_R) ofs = 0;
- else if (snode->flag & SNODE_SHOW_G) ofs = 1;
- else ofs = 2;
-#else
- if (snode->flag & SNODE_SHOW_R) ofs = 1;
- else if (snode->flag & SNODE_SHOW_G) ofs = 2;
- else ofs = 3;
-#endif
-
- glPixelZoom(snode->zoom, snode->zoom);
- /* swap bytes, so alpha is most significant one, then just draw it as luminance int */
-
- glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_LUMINANCE, GL_UNSIGNED_INT,
- display_buffer - (4 - ofs));
-
- glPixelZoom(1.0f, 1.0f);
- }
- else if (snode->flag & SNODE_SHOW_ALPHA) {
- display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
-
- glPixelZoom(snode->zoom, snode->zoom);
- /* swap bytes, so alpha is most significant one, then just draw it as luminance int */
-#ifdef __BIG_ENDIAN__
- glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
-#endif
- glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_LUMINANCE, GL_UNSIGNED_INT, display_buffer);
-
-#ifdef __BIG_ENDIAN__
- glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
-#endif
- glPixelZoom(1.0f, 1.0f);
+
+ if (snode->flag & SNODE_SHOW_R)
+ shuffle[0] = 1.0f;
+ else if (snode->flag & SNODE_SHOW_G)
+ shuffle[1] = 1.0f;
+ else if (snode->flag & SNODE_SHOW_B)
+ shuffle[2] = 1.0f;
+ else
+ shuffle[3] = 1.0f;
+
+ IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR);
+ GPU_shader_uniform_vector(state.shader, GPU_shader_get_uniform(state.shader, "shuffle"), 4, 1, shuffle);
+
+ immDrawPixelsTex(&state, x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST,
+ display_buffer, snode->zoom, snode->zoom, NULL);
+
+ GPU_shader_unbind();
}
else if (snode->flag & SNODE_USE_ALPHA) {
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glPixelZoom(snode->zoom, snode->zoom);
-
- glaDrawImBuf_glsl_ctx(C, ibuf, x, y, GL_NEAREST);
-
- glPixelZoom(1.0f, 1.0f);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+
+ glaDrawImBuf_glsl_ctx(C, ibuf, x, y, GL_NEAREST, snode->zoom, snode->zoom);
+
glDisable(GL_BLEND);
}
else {
- glPixelZoom(snode->zoom, snode->zoom);
-
- glaDrawImBuf_glsl_ctx(C, ibuf, x, y, GL_NEAREST);
-
- glPixelZoom(1.0f, 1.0f);
+ glaDrawImBuf_glsl_ctx(C, ibuf, x, y, GL_NEAREST, snode->zoom, snode->zoom);
}
if (cache_handle)
@@ -3345,30 +3236,33 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode, b
viewer_border->ymin < viewer_border->ymax)
{
rcti pixel_border;
- UI_ThemeColor(TH_ACTIVE);
BLI_rcti_init(&pixel_border,
x + snode->zoom * viewer_border->xmin * ibuf->x,
x + snode->zoom * viewer_border->xmax * ibuf->x,
y + snode->zoom * viewer_border->ymin * ibuf->y,
y + snode->zoom * viewer_border->ymax * ibuf->y);
- glaDrawBorderCorners(&pixel_border, 1.0f, 1.0f);
+
+ unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformThemeColor(TH_ACTIVE);
+
+ immDrawBorderCorners(pos, &pixel_border, 1.0f, 1.0f);
+
+ immUnbindProgram();
}
}
-
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
+
+ gpuPopProjectionMatrix();
+ gpuPopMatrix();
}
BKE_image_release_ibuf(ima, ibuf, lock);
}
-
-/* if v2d not NULL, it clips and returns 0 if not visible */
-bool node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, float coord_array[][2], int resol)
+/* return quadratic beziers points for a given nodelink and clip if v2d is not NULL. */
+static bool node_link_bezier_handles(View2D *v2d, SpaceNode *snode, bNodeLink *link, float vec[4][2])
{
- float dist, vec[4][2];
+ float dist;
float deltax, deltay;
float cursor[2] = {0.0f, 0.0f};
int toreroute, fromreroute;
@@ -3436,13 +3330,23 @@ bool node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, flo
vec[2][0] = vec[3][0] - dist;
vec[2][1] = vec[3][1];
}
+
if (v2d && min_ffff(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) > v2d->cur.xmax) {
- /* clipped */
+ return 0; /* clipped */
}
else if (v2d && max_ffff(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) < v2d->cur.xmin) {
- /* clipped */
+ return 0; /* clipped */
}
- else {
+
+ return 1;
+}
+
+/* if v2d not NULL, it clips and returns 0 if not visible */
+bool node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, float coord_array[][2], int resol)
+{
+ float vec[4][2];
+
+ if (node_link_bezier_handles(v2d, snode, link, vec)) {
/* always do all three, to prevent data hanging around */
BKE_curve_forward_diff_bezier(vec[0][0], vec[1][0], vec[2][0], vec[3][0],
coord_array[0] + 0, resol, sizeof(float) * 2);
@@ -3454,186 +3358,242 @@ bool node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, flo
return 0;
}
+#define NODELINK_GROUP_SIZE 256
#define LINK_RESOL 24
-#define LINK_ARROW 12 /* position of arrow on the link, LINK_RESOL/2 */
-#define ARROW_SIZE (7 * UI_DPI_FAC)
-void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link,
- int th_col1, bool do_shaded, int th_col2, bool do_triple, int th_col3)
-{
- float coord_array[LINK_RESOL + 1][2];
-
- if (node_link_bezier_points(v2d, snode, link, coord_array, LINK_RESOL)) {
- float dist, spline_step = 0.0f;
- int i;
- int drawarrow;
- /* store current linewidth */
- float linew;
- float arrow[2], arrow1[2], arrow2[2];
- glGetFloatv(GL_LINE_WIDTH, &linew);
-
- /* we can reuse the dist variable here to increment the GL curve eval amount*/
- dist = 1.0f / (float)LINK_RESOL;
-
- glEnable(GL_LINE_SMOOTH);
-
- drawarrow = ((link->tonode && (link->tonode->type == NODE_REROUTE)) &&
- (link->fromnode && (link->fromnode->type == NODE_REROUTE)));
-
- if (drawarrow) {
- /* draw arrow in line segment LINK_ARROW */
- float d_xy[2], len;
-
- sub_v2_v2v2(d_xy, coord_array[LINK_ARROW], coord_array[LINK_ARROW - 1]);
- len = len_v2(d_xy);
- mul_v2_fl(d_xy, ARROW_SIZE / len);
- arrow1[0] = coord_array[LINK_ARROW][0] - d_xy[0] + d_xy[1];
- arrow1[1] = coord_array[LINK_ARROW][1] - d_xy[1] - d_xy[0];
- arrow2[0] = coord_array[LINK_ARROW][0] - d_xy[0] - d_xy[1];
- arrow2[1] = coord_array[LINK_ARROW][1] - d_xy[1] + d_xy[0];
- arrow[0] = coord_array[LINK_ARROW][0];
- arrow[1] = coord_array[LINK_ARROW][1];
+#define LINK_WIDTH (2.5f * UI_DPI_FAC)
+#define ARROW_SIZE (7 * UI_DPI_FAC)
+
+static float arrow_verts[3][2] = {{-1.0f, 1.0f}, {0.0f, 0.0f}, {-1.0f, -1.0f}};
+static float arrow_expand_axis[3][2] = {{0.7071f, 0.7071f}, {M_SQRT2, 0.0f}, {0.7071f, -0.7071f}};
+
+struct {
+ Gwn_Batch *batch; /* for batching line together */
+ Gwn_Batch *batch_single; /* for single line */
+ Gwn_VertBuf *inst_vbo;
+ unsigned int p0_id, p1_id, p2_id, p3_id;
+ unsigned int colid_id;
+ Gwn_VertBufRaw p0_step, p1_step, p2_step, p3_step;
+ Gwn_VertBufRaw colid_step;
+ unsigned int count;
+ bool enabled;
+} g_batch_link = {0};
+
+static void nodelink_batch_reset(void)
+{
+ GWN_vertbuf_attr_get_raw_data(g_batch_link.inst_vbo, g_batch_link.p0_id, &g_batch_link.p0_step);
+ GWN_vertbuf_attr_get_raw_data(g_batch_link.inst_vbo, g_batch_link.p1_id, &g_batch_link.p1_step);
+ GWN_vertbuf_attr_get_raw_data(g_batch_link.inst_vbo, g_batch_link.p2_id, &g_batch_link.p2_step);
+ GWN_vertbuf_attr_get_raw_data(g_batch_link.inst_vbo, g_batch_link.p3_id, &g_batch_link.p3_step);
+ GWN_vertbuf_attr_get_raw_data(g_batch_link.inst_vbo, g_batch_link.colid_id, &g_batch_link.colid_step);
+ g_batch_link.count = 0;
+}
+
+static void set_nodelink_vertex(
+ Gwn_VertBuf *vbo,
+ unsigned int uv_id, unsigned int pos_id, unsigned int exp_id, unsigned int v,
+ const unsigned char uv[2], const float pos[2], const float exp[2])
+{
+ GWN_vertbuf_attr_set(vbo, uv_id, v, uv);
+ GWN_vertbuf_attr_set(vbo, pos_id, v, pos);
+ GWN_vertbuf_attr_set(vbo, exp_id, v, exp);
+}
+
+static void nodelink_batch_init(void)
+{
+ Gwn_VertFormat format = {0};
+ unsigned int uv_id = GWN_vertformat_attr_add(&format, "uv", GWN_COMP_U8, 2, GWN_FETCH_INT_TO_FLOAT_UNIT);
+ unsigned int pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ unsigned int expand_id = GWN_vertformat_attr_add(&format, "expand", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format_ex(&format, GWN_USAGE_STATIC);
+ int vcount = LINK_RESOL * 2; /* curve */
+ vcount += 2; /* restart strip */
+ vcount += 3 * 2; /* arrow */
+ vcount *= 2; /* shadow */
+ vcount += 2; /* restart strip */
+ GWN_vertbuf_data_alloc(vbo, vcount);
+ int v = 0;
+
+ for (int k = 0; k < 2; ++k) {
+ unsigned char uv[2] = {0, 0};
+ float pos[2] = {0.0f, 0.0f};
+ float exp[2] = {0.0f, 1.0f};
+
+ /* restart */
+ if (k == 1)
+ set_nodelink_vertex(vbo, uv_id, pos_id, expand_id, v++, uv, pos, exp);
+
+ /* curve strip */
+ for (int i = 0; i < LINK_RESOL; ++i) {
+ uv[0] = 255 * (i / (float)(LINK_RESOL - 1));
+ uv[1] = 0;
+ set_nodelink_vertex(vbo, uv_id, pos_id, expand_id, v++, uv, pos, exp);
+ uv[1] = 255;
+ set_nodelink_vertex(vbo, uv_id, pos_id, expand_id, v++, uv, pos, exp);
}
- if (do_triple) {
- UI_ThemeColorShadeAlpha(th_col3, -80, -120);
- glLineWidth(4.0f);
-
- glBegin(GL_LINE_STRIP);
- for (i = 0; i <= LINK_RESOL; i++) {
- glVertex2fv(coord_array[i]);
- }
- glEnd();
- if (drawarrow) {
- glBegin(GL_LINE_STRIP);
- glVertex2fv(arrow1);
- glVertex2fv(arrow);
- glVertex2fv(arrow2);
- glEnd();
- }
+ /* restart */
+ set_nodelink_vertex(vbo, uv_id, pos_id, expand_id, v++, uv, pos, exp);
+
+ uv[0] = 127;
+ uv[1] = 0;
+ copy_v2_v2(pos, arrow_verts[0]);
+ copy_v2_v2(exp, arrow_expand_axis[0]);
+ set_nodelink_vertex(vbo, uv_id, pos_id, expand_id, v++, uv, pos, exp);
+ /* arrow */
+ for (int i = 0; i < 3; ++i) {
+ uv[1] = 0;
+ copy_v2_v2(pos, arrow_verts[i]);
+ copy_v2_v2(exp, arrow_expand_axis[i]);
+ set_nodelink_vertex(vbo, uv_id, pos_id, expand_id, v++, uv, pos, exp);
+
+ uv[1] = 255;
+ set_nodelink_vertex(vbo, uv_id, pos_id, expand_id, v++, uv, pos, exp);
}
-
- /* XXX using GL_LINES for shaded node lines is a workaround
- * for Intel hardware, this breaks with GL_LINE_STRIP and
- * changing color in begin/end blocks.
- */
- glLineWidth(1.5f);
- if (do_shaded) {
- glBegin(GL_LINES);
- for (i = 0; i < LINK_RESOL; i++) {
- UI_ThemeColorBlend(th_col1, th_col2, spline_step);
- glVertex2fv(coord_array[i]);
-
- UI_ThemeColorBlend(th_col1, th_col2, spline_step + dist);
- glVertex2fv(coord_array[i + 1]);
-
- spline_step += dist;
- }
- glEnd();
- }
- else {
- UI_ThemeColor(th_col1);
- glBegin(GL_LINE_STRIP);
- for (i = 0; i <= LINK_RESOL; i++) {
- glVertex2fv(coord_array[i]);
- }
- glEnd();
- }
-
- if (drawarrow) {
- glBegin(GL_LINE_STRIP);
- glVertex2fv(arrow1);
- glVertex2fv(arrow);
- glVertex2fv(arrow2);
- glEnd();
- }
-
- glDisable(GL_LINE_SMOOTH);
+
+ /* restart */
+ if (k == 0)
+ set_nodelink_vertex(vbo, uv_id, pos_id, expand_id, v++, uv, pos, exp);
}
+
+ g_batch_link.batch = GWN_batch_create_ex(GWN_PRIM_TRI_STRIP, vbo, NULL, GWN_BATCH_OWNS_VBO);
+ gpu_batch_presets_register(g_batch_link.batch);
+
+ g_batch_link.batch_single = GWN_batch_create_ex(GWN_PRIM_TRI_STRIP, vbo, NULL, 0);
+ gpu_batch_presets_register(g_batch_link.batch_single);
+
+ /* Instances data */
+ Gwn_VertFormat format_inst = {0};
+ g_batch_link.p0_id = GWN_vertformat_attr_add(&format_inst, "P0", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ g_batch_link.p1_id = GWN_vertformat_attr_add(&format_inst, "P1", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ g_batch_link.p2_id = GWN_vertformat_attr_add(&format_inst, "P2", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ g_batch_link.p3_id = GWN_vertformat_attr_add(&format_inst, "P3", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ g_batch_link.colid_id = GWN_vertformat_attr_add(&format_inst, "colid_doarrow", GWN_COMP_U8, 4, GWN_FETCH_INT);
+ g_batch_link.inst_vbo = GWN_vertbuf_create_with_format_ex(&format_inst, GWN_USAGE_STREAM);
+ GWN_vertbuf_data_alloc(g_batch_link.inst_vbo, NODELINK_GROUP_SIZE); /* Alloc max count but only draw the range we need. */
+
+ GWN_batch_instbuf_set(g_batch_link.batch, g_batch_link.inst_vbo, true);
+
+ nodelink_batch_reset();
}
-#if 0 /* not used in 2.5x yet */
-static void node_link_straight_points(View2D *UNUSED(v2d), SpaceNode *snode, bNodeLink *link, float coord_array[][2])
+static char nodelink_get_color_id(int th_col)
{
- if (link->fromsock) {
- coord_array[0][0] = link->fromsock->locx;
- coord_array[0][1] = link->fromsock->locy;
- }
- else {
- if (snode == NULL) return;
- coord_array[0][0] = snode->mx;
- coord_array[0][1] = snode->my;
- }
- if (link->tosock) {
- coord_array[1][0] = link->tosock->locx;
- coord_array[1][1] = link->tosock->locy;
- }
- else {
- if (snode == NULL) return;
- coord_array[1][0] = snode->mx;
- coord_array[1][1] = snode->my;
+ switch (th_col) {
+ case TH_WIRE: return 1;
+ case TH_WIRE_INNER: return 2;
+ case TH_ACTIVE: return 3;
+ case TH_EDGE_SELECT: return 4;
+ case TH_REDALERT: return 5;
}
+ return 0;
}
-void node_draw_link_straight(View2D *v2d, SpaceNode *snode, bNodeLink *link,
- int th_col1, int do_shaded, int th_col2, int do_triple, int th_col3)
+static void nodelink_batch_draw(SpaceNode *snode)
{
- float coord_array[2][2];
- int i;
-
- node_link_straight_points(v2d, snode, link, coord_array);
-
- glEnable(GL_LINE_SMOOTH);
-
- if (do_triple) {
- UI_ThemeColorShadeAlpha(th_col3, -80, -120);
- glLineWidth(4.0f);
-
- glBegin(GL_LINES);
- glVertex2fv(coord_array[0]);
- glVertex2fv(coord_array[1]);
- glEnd();
+ if (g_batch_link.count == 0)
+ return;
+
+ glEnable(GL_BLEND);
+
+ float colors[6][4] = {{0.0f}};
+ UI_GetThemeColor4fv(TH_WIRE_INNER, colors[nodelink_get_color_id(TH_WIRE_INNER)]);
+ UI_GetThemeColor4fv(TH_WIRE, colors[nodelink_get_color_id(TH_WIRE)]);
+ UI_GetThemeColor4fv(TH_ACTIVE, colors[nodelink_get_color_id(TH_ACTIVE)]);
+ UI_GetThemeColor4fv(TH_EDGE_SELECT, colors[nodelink_get_color_id(TH_EDGE_SELECT)]);
+ UI_GetThemeColor4fv(TH_REDALERT, colors[nodelink_get_color_id(TH_REDALERT)]);
+
+ GWN_vertbuf_vertex_count_set(g_batch_link.inst_vbo, g_batch_link.count);
+ GWN_vertbuf_use(g_batch_link.inst_vbo); /* force update. */
+
+ GWN_batch_program_set_builtin(g_batch_link.batch, GPU_SHADER_2D_NODELINK_INST);
+ GWN_batch_uniform_4fv_array(g_batch_link.batch, "colors", 6, (float *)colors);
+ GWN_batch_uniform_1f(g_batch_link.batch, "expandSize", snode->aspect * LINK_WIDTH);
+ GWN_batch_uniform_1f(g_batch_link.batch, "arrowSize", ARROW_SIZE);
+ GWN_batch_draw(g_batch_link.batch);
+
+ nodelink_batch_reset();
+
+ glDisable(GL_BLEND);
+}
+
+void nodelink_batch_start(SpaceNode *UNUSED(snode))
+{
+ g_batch_link.enabled = true;
+}
+
+void nodelink_batch_end(SpaceNode *snode)
+{
+ nodelink_batch_draw(snode);
+ g_batch_link.enabled = false;
+}
+
+static void nodelink_batch_add_link(
+ SpaceNode *snode,
+ const float p0[2], const float p1[2], const float p2[2], const float p3[2],
+ int th_col1, int th_col2, int th_col3, bool drawarrow)
+{
+ /* Only allow these colors. If more is needed, you need to modify the shader accordingly. */
+ BLI_assert(ELEM(th_col1, TH_WIRE_INNER, TH_WIRE, TH_ACTIVE, TH_EDGE_SELECT, TH_REDALERT));
+ BLI_assert(ELEM(th_col2, TH_WIRE_INNER, TH_WIRE, TH_ACTIVE, TH_EDGE_SELECT, TH_REDALERT));
+ BLI_assert(ELEM(th_col3, TH_WIRE, -1));
+
+ g_batch_link.count++;
+ copy_v2_v2(GWN_vertbuf_raw_step(&g_batch_link.p0_step), p0);
+ copy_v2_v2(GWN_vertbuf_raw_step(&g_batch_link.p1_step), p1);
+ copy_v2_v2(GWN_vertbuf_raw_step(&g_batch_link.p2_step), p2);
+ copy_v2_v2(GWN_vertbuf_raw_step(&g_batch_link.p3_step), p3);
+ char *colid = GWN_vertbuf_raw_step(&g_batch_link.colid_step);
+ colid[0] = nodelink_get_color_id(th_col1);
+ colid[1] = nodelink_get_color_id(th_col2);
+ colid[2] = nodelink_get_color_id(th_col3);
+ colid[3] = drawarrow;
+
+ if (g_batch_link.count == NODELINK_GROUP_SIZE) {
+ nodelink_batch_draw(snode);
}
-
- UI_ThemeColor(th_col1);
- glLineWidth(1.5f);
-
- /* XXX using GL_LINES for shaded node lines is a workaround
- * for Intel hardware, this breaks with GL_LINE_STRIP and
- * changing color in begin/end blocks.
- */
- if (do_shaded) {
- glBegin(GL_LINES);
- for (i = 0; i < LINK_RESOL - 1; ++i) {
- float t = (float)i / (float)(LINK_RESOL - 1);
- UI_ThemeColorBlend(th_col1, th_col2, t);
- glVertex2f((1.0f - t) * coord_array[0][0] + t * coord_array[1][0],
- (1.0f - t) * coord_array[0][1] + t * coord_array[1][1]);
-
- t = (float)(i + 1) / (float)(LINK_RESOL - 1);
- UI_ThemeColorBlend(th_col1, th_col2, t);
- glVertex2f((1.0f - t) * coord_array[0][0] + t * coord_array[1][0],
- (1.0f - t) * coord_array[0][1] + t * coord_array[1][1]);
+}
+
+/* don't do shadows if th_col3 is -1. */
+void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link,
+ int th_col1, int th_col2, int th_col3)
+{
+ float vec[4][2];
+
+ if (node_link_bezier_handles(v2d, snode, link, vec)) {
+ int drawarrow = ((link->tonode && (link->tonode->type == NODE_REROUTE)) &&
+ (link->fromnode && (link->fromnode->type == NODE_REROUTE)));
+
+ if (g_batch_link.batch == NULL) {
+ nodelink_batch_init();
}
- glEnd();
- }
- else {
- glBegin(GL_LINE_STRIP);
- for (i = 0; i < LINK_RESOL; ++i) {
- float t = (float)i / (float)(LINK_RESOL - 1);
- glVertex2f((1.0f - t) * coord_array[0][0] + t * coord_array[1][0],
- (1.0f - t) * coord_array[0][1] + t * coord_array[1][1]);
+
+ if (g_batch_link.enabled) {
+ /* Add link to batch. */
+ nodelink_batch_add_link(snode, vec[0], vec[1], vec[2], vec[3], th_col1, th_col2, th_col3, drawarrow);
+ }
+ else {
+ /* Draw single link. */
+ float colors[3][4] = {{0.0f}};
+ if (th_col3 != -1) {
+ UI_GetThemeColor4fv(th_col3, colors[0]);
+ }
+ UI_GetThemeColor4fv(th_col1, colors[1]);
+ UI_GetThemeColor4fv(th_col2, colors[2]);
+
+ Gwn_Batch *batch = g_batch_link.batch_single;
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_NODELINK);
+ GWN_batch_uniform_2fv_array(batch, "bezierPts", 4, (float *)vec);
+ GWN_batch_uniform_4fv_array(batch, "colors", 3, (float *)colors);
+ GWN_batch_uniform_1f(batch, "expandSize", snode->aspect * LINK_WIDTH);
+ GWN_batch_uniform_1f(batch, "arrowSize", ARROW_SIZE);
+ GWN_batch_uniform_1i(batch, "doArrow", drawarrow);
+ GWN_batch_draw(batch);
}
- glEnd();
}
-
- glDisable(GL_LINE_SMOOTH);
}
-#endif
/* note; this is used for fake links in groups too */
void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link)
{
- bool do_shaded = false;
- bool do_triple = false;
int th_col1 = TH_WIRE_INNER, th_col2 = TH_WIRE_INNER, th_col3 = TH_WIRE;
if (link->fromsock == NULL && link->tosock == NULL)
@@ -3641,8 +3601,7 @@ void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link)
/* new connection */
if (!link->fromsock || !link->tosock) {
- th_col1 = TH_ACTIVE;
- do_triple = true;
+ th_col1 = th_col2 = TH_ACTIVE;
}
else {
/* going to give issues once... */
@@ -3663,39 +3622,38 @@ void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link)
if (link->tonode && link->tonode->flag & SELECT)
th_col2 = TH_EDGE_SELECT;
}
- do_shaded = true;
- do_triple = true;
}
else {
- th_col1 = TH_REDALERT;
+ th_col1 = th_col2 = TH_REDALERT;
+ // th_col3 = -1; /* no shadow */
}
}
- node_draw_link_bezier(v2d, snode, link, th_col1, do_shaded, th_col2, do_triple, th_col3);
+ node_draw_link_bezier(v2d, snode, link, th_col1, th_col2, th_col3);
// node_draw_link_straight(v2d, snode, link, th_col1, do_shaded, th_col2, do_triple, th_col3);
}
-void ED_node_draw_snap(View2D *v2d, const float cent[2], float size, NodeBorder border)
+void ED_node_draw_snap(View2D *v2d, const float cent[2], float size, NodeBorder border, unsigned pos)
{
- glBegin(GL_LINES);
+ immBegin(GWN_PRIM_LINES, 4);
if (border & (NODE_LEFT | NODE_RIGHT)) {
- glVertex2f(cent[0], v2d->cur.ymin);
- glVertex2f(cent[0], v2d->cur.ymax);
+ immVertex2f(pos, cent[0], v2d->cur.ymin);
+ immVertex2f(pos, cent[0], v2d->cur.ymax);
}
else {
- glVertex2f(cent[0], cent[1] - size);
- glVertex2f(cent[0], cent[1] + size);
+ immVertex2f(pos, cent[0], cent[1] - size);
+ immVertex2f(pos, cent[0], cent[1] + size);
}
if (border & (NODE_TOP | NODE_BOTTOM)) {
- glVertex2f(v2d->cur.xmin, cent[1]);
- glVertex2f(v2d->cur.xmax, cent[1]);
+ immVertex2f(pos, v2d->cur.xmin, cent[1]);
+ immVertex2f(pos, v2d->cur.xmax, cent[1]);
}
else {
- glVertex2f(cent[0] - size, cent[1]);
- glVertex2f(cent[0] + size, cent[1]);
+ immVertex2f(pos, cent[0] - size, cent[1]);
+ immVertex2f(pos, cent[0] + size, cent[1]);
}
- glEnd();
+ immEnd();
}
diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c
index ec35727d176..c200c5a7612 100644
--- a/source/blender/editors/space_node/node_add.c
+++ b/source/blender/editors/space_node/node_add.c
@@ -316,10 +316,7 @@ static int node_add_file_exec(bContext *C, wmOperator *op)
switch (snode->nodetree->type) {
case NTREE_SHADER:
- if (BKE_scene_use_new_shading_nodes(CTX_data_scene(C)))
- type = SH_NODE_TEX_IMAGE;
- else
- type = SH_NODE_TEXTURE;
+ type = SH_NODE_TEX_IMAGE;
break;
case NTREE_TEXTURE:
type = TEX_NODE_IMAGE;
@@ -340,14 +337,7 @@ static int node_add_file_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- if (type == SH_NODE_TEXTURE) {
- Tex *tex = BKE_texture_add(CTX_data_main(C), DATA_(ima->id.name));
- tex->ima = ima;
- node->id = (ID *)tex;
- WM_event_add_notifier(C, NC_TEXTURE | NA_ADDED, node->id);
- }
- else
- node->id = (ID *)ima;
+ node->id = (ID *)ima;
/* When adding new image file via drag-drop we need to load imbuf in order
* to get proper image source.
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index e56a3a549fc..ae810b0fde0 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -44,16 +44,21 @@
#include "BLT_translation.h"
#include "BKE_context.h"
-#include "BKE_depsgraph.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_node.h"
+#include "DEG_depsgraph.h"
+
#include "BLF_api.h"
-#include "BIF_gl.h"
#include "BIF_glutil.h"
+#include "GPU_draw.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+#include "GPU_matrix.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -128,10 +133,10 @@ void ED_node_tag_update_id(ID *id)
* all the users of this tree will have update
* flushed from the tree,
*/
- DAG_id_tag_update(&ntree->id, 0);
+ DEG_id_tag_update(&ntree->id, 0);
if (ntree->type == NTREE_SHADER) {
- DAG_id_tag_update(id, 0);
+ DEG_id_tag_update(id, 0);
if (GS(id->name) == ID_MA)
WM_main_add_notifier(NC_MATERIAL | ND_SHADING, id);
@@ -144,12 +149,12 @@ void ED_node_tag_update_id(ID *id)
WM_main_add_notifier(NC_SCENE | ND_NODES, id);
}
else if (ntree->type == NTREE_TEXTURE) {
- DAG_id_tag_update(id, 0);
+ DEG_id_tag_update(id, 0);
WM_main_add_notifier(NC_TEXTURE | ND_NODES, id);
}
else if (id == &ntree->id) {
/* node groups */
- DAG_id_tag_update(id, 0);
+ DEG_id_tag_update(id, 0);
}
}
@@ -616,112 +621,23 @@ static void node_draw_mute_line(View2D *v2d, SpaceNode *snode, bNode *node)
bNodeLink *link;
glEnable(GL_BLEND);
- glEnable(GL_LINE_SMOOTH);
for (link = node->internal_links.first; link; link = link->next)
- node_draw_link_bezier(v2d, snode, link, TH_REDALERT, 0, TH_WIRE, 0, TH_WIRE);
-
- glDisable(GL_BLEND);
- glDisable(GL_LINE_SMOOTH);
-}
-
-static void node_socket_shape_draw(
- float x, float y, float size, const float col[4], bool highlight,
- const float coords[][2], int coords_len)
-{
- int a;
-
- glColor4fv(col);
-
- glEnable(GL_BLEND);
- glBegin(GL_POLYGON);
- for (a = 0; a < coords_len; a++) {
- glVertex2f(x + size * coords[a][0], y + size * coords[a][1]);
- }
- glEnd();
- glDisable(GL_BLEND);
+ node_draw_link_bezier(v2d, snode, link, TH_REDALERT, TH_REDALERT, -1);
- if (highlight) {
- UI_ThemeColor(TH_TEXT_HI);
- glLineWidth(1.5f);
- }
- else {
- glColor4ub(0, 0, 0, 150);
- }
- glEnable(GL_BLEND);
- glEnable(GL_LINE_SMOOTH);
- glBegin(GL_LINE_LOOP);
- for (a = 0; a < coords_len; a++) {
- glVertex2f(x + size * coords[a][0], y + size * coords[a][1]);
- }
- glEnd();
- glDisable(GL_LINE_SMOOTH);
glDisable(GL_BLEND);
}
-
-void node_socket_draw(const bContext *C, bNodeTree *ntree, bNode *node, bNodeSocket *sock, float size, bool highlight)
+static void node_socket_circle_draw(const bContext *C, bNodeTree *ntree, PointerRNA node_ptr, bNodeSocket *sock, unsigned pos, unsigned col)
{
- PointerRNA ptr, node_ptr;
+ PointerRNA ptr;
float color[4];
RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr);
- RNA_pointer_create((ID *)ntree, &RNA_Node, node, &node_ptr);
sock->typeinfo->draw_color((bContext *)C, &ptr, &node_ptr, color);
-
- /* 16 values of {sin, cos} function */
- const float shape_circle[16][2] = {
- {0.00000000f, 1.00000000f},
- {0.39435585f, 0.91895781f},
- {0.72479278f, 0.68896691f},
- {0.93775213f, 0.34730525f},
- {0.99871650f, -0.05064916f},
- {0.89780453f, -0.44039415f},
- {0.65137248f, -0.75875812f},
- {0.29936312f, -0.95413925f},
- {-0.10116832f, -0.99486932f},
- {-0.48530196f, -0.87434661f},
- {-0.79077573f, -0.61210598f},
- {-0.96807711f, -0.25065253f},
- {-0.98846832f, 0.15142777f},
- {-0.84864425f, 0.52896401f},
- {-0.57126821f, 0.82076344f},
- {-0.20129852f, 0.97952994f }
- };
-
- const float shape_diamond[4][2] = {
- {0.0f, 1.2f},
- {1.2f, 0.0f},
- {0.0f, -1.2f},
- {-1.2f, 0.0f},
- };
-
- const float shape_square[4][2] = {
- {-0.9f, 0.9f},
- {0.9f, 0.9f},
- {0.9f, -0.9f},
- {-0.9f, -0.9f},
- };
-
- const float (*shape)[2];
- int shape_len;
- switch (sock->draw_shape) {
- default:
- case SOCK_DRAW_SHAPE_CIRCLE:
- shape = shape_circle;
- shape_len = ARRAY_SIZE(shape_circle);
- break;
- case SOCK_DRAW_SHAPE_DIAMOND:
- shape = shape_diamond;
- shape_len = ARRAY_SIZE(shape_diamond);
- break;
- case SOCK_DRAW_SHAPE_SQUARE:
- shape = shape_square;
- shape_len = ARRAY_SIZE(shape_square);
- break;
- }
-
- node_socket_shape_draw(sock->locx, sock->locy, size, color, highlight, shape, shape_len);
+
+ immAttrib4fv(col, color);
+ immVertex2f(pos, sock->locx, sock->locy);
}
/* ************** Socket callbacks *********** */
@@ -730,10 +646,15 @@ static void node_draw_preview_background(float tile, rctf *rect)
{
float x, y;
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
/* draw checkerboard backdrop to show alpha */
- glColor3ub(120, 120, 120);
- glRectf(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
- glColor3ub(160, 160, 160);
+ immUniformColor3ub(120, 120, 120);
+ immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
+ immUniformColor3ub(160, 160, 160);
for (y = rect->ymin; y < rect->ymax; y += tile * 2) {
for (x = rect->xmin; x < rect->xmax; x += tile * 2) {
@@ -744,7 +665,7 @@ static void node_draw_preview_background(float tile, rctf *rect)
if (y + tile > rect->ymax)
tiley = rect->ymax - y;
- glRectf(x, y, x + tilex, y + tiley);
+ immRectf(pos, x, y, x + tilex, y + tiley);
}
}
for (y = rect->ymin + tile; y < rect->ymax; y += tile * 2) {
@@ -756,9 +677,10 @@ static void node_draw_preview_background(float tile, rctf *rect)
if (y + tile > rect->ymax)
tiley = rect->ymax - y;
- glRectf(x, y, x + tilex, y + tiley);
+ immRectf(pos, x, y, x + tilex, y + tiley);
}
}
+ immUnbindProgram();
}
/* not a callback */
@@ -789,17 +711,19 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv)
node_draw_preview_background(BLI_rctf_size_x(prv) / 10.0f, &draw_rect);
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /* premul graphics */
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); /* premul graphics */
- glColor4f(1.0, 1.0, 1.0, 1.0);
- glPixelZoom(scale, scale);
- glaDrawPixelsTex(draw_rect.xmin, draw_rect.ymin, preview->xsize, preview->ysize, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR, preview->rect);
- glPixelZoom(1.0f, 1.0f);
+ IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
+ immDrawPixelsTex(&state, draw_rect.xmin, draw_rect.ymin, preview->xsize, preview->ysize, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR, preview->rect,
+ scale, scale, NULL);
glDisable(GL_BLEND);
- UI_ThemeColorShadeAlpha(TH_BACK, -15, +100);
- fdrawbox(draw_rect.xmin, draw_rect.ymin, draw_rect.xmax, draw_rect.ymax);
+ unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformThemeColorShadeAlpha(TH_BACK, -15, +100);
+ imm_draw_box_wire_2d(pos, draw_rect.xmin, draw_rect.ymin, draw_rect.xmax, draw_rect.ymax);
+ immUnbindProgram();
}
/* common handle function for operator buttons that need to select the node first */
@@ -824,32 +748,139 @@ void node_draw_shadow(SpaceNode *snode, bNode *node, float radius, float alpha)
else {
const float margin = 3.0f;
- glColor4f(0.0f, 0.0f, 0.0f, 0.33f);
- glEnable(GL_BLEND);
- UI_draw_roundbox(rct->xmin - margin, rct->ymin - margin,
- rct->xmax + margin, rct->ymax + margin, radius + margin);
- glDisable(GL_BLEND);
+ float color[4] = {0.0f, 0.0f, 0.0f, 0.33f};
+ UI_draw_roundbox_aa(true, rct->xmin - margin, rct->ymin - margin,
+ rct->xmax + margin, rct->ymax + margin, radius + margin, color);
+ }
+}
+
+void node_draw_sockets(View2D *v2d, const bContext *C, bNodeTree *ntree, bNode *node, bool draw_outputs, bool select_all)
+{
+ const unsigned int total_input_ct = BLI_listbase_count(&node->inputs);
+ const unsigned int total_output_ct = BLI_listbase_count(&node->outputs);
+
+ if (total_input_ct + total_output_ct == 0) {
+ return;
+ }
+
+ PointerRNA node_ptr;
+ RNA_pointer_create((ID *)ntree, &RNA_Node, node, &node_ptr);
+
+ float scale;
+ UI_view2d_scale_get(v2d, &scale, NULL);
+
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ unsigned int col = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
+
+ glEnable(GL_BLEND);
+ GPU_enable_program_point_size();
+
+ immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_VARYING_COLOR_OUTLINE_AA);
+
+ /* set handle size */
+ immUniform1f("size", 2.0f * NODE_SOCKSIZE * scale); /* 2 * size to have diameter */
+
+ if (!select_all) {
+ /* outline for unselected sockets */
+ immUniform1f("outlineWidth", 1.0f);
+ immUniform4f("outlineColor", 0.0f, 0.0f, 0.0f, 0.6f);
+
+ immBeginAtMost(GWN_PRIM_POINTS, total_input_ct + total_output_ct);
+ }
+
+ /* socket inputs */
+ short selected_input_ct = 0;
+ bNodeSocket *sock;
+ for (sock = node->inputs.first; sock; sock = sock->next) {
+ if (nodeSocketIsHidden(sock))
+ continue;
+ if (select_all || (sock->flag & SELECT)) {
+ ++selected_input_ct;
+ continue;
+ }
+
+ node_socket_circle_draw(C, ntree, node_ptr, sock, pos, col);
+ }
+
+ /* socket outputs */
+ short selected_output_ct = 0;
+ if (draw_outputs) {
+ for (sock = node->outputs.first; sock; sock = sock->next) {
+ if (nodeSocketIsHidden(sock))
+ continue;
+ if (select_all || (sock->flag & SELECT)) {
+ ++selected_output_ct;
+ continue;
+ }
+
+ node_socket_circle_draw(C, ntree, node_ptr, sock, pos, col);
+ }
+ }
+
+ if (!select_all) {
+ immEnd();
+ }
+
+ /* go back and draw selected sockets */
+ if (selected_input_ct + selected_output_ct > 0) {
+ /* outline for selected sockets */
+ float c[3];
+ UI_GetThemeColor3fv(TH_TEXT_HI, c);
+ immUniform4f("outlineColor", c[0], c[1], c[2], 1.0f);
+ immUniform1f("outlineWidth", 1.5f);
+
+ immBegin(GWN_PRIM_POINTS, selected_input_ct + selected_output_ct);
+
+ if (selected_input_ct) {
+ /* socket inputs */
+ for (sock = node->inputs.first; sock; sock = sock->next) {
+ if (nodeSocketIsHidden(sock))
+ continue;
+ if (select_all || (sock->flag & SELECT)) {
+ node_socket_circle_draw(C, ntree, node_ptr, sock, pos, col);
+ if (--selected_input_ct == 0)
+ break; /* stop as soon as last one is drawn */
+ }
+ }
+ }
+
+ if (selected_output_ct) {
+ /* socket outputs */
+ for (sock = node->outputs.first; sock; sock = sock->next) {
+ if (nodeSocketIsHidden(sock))
+ continue;
+ if (select_all || (sock->flag & SELECT)) {
+ node_socket_circle_draw(C, ntree, node_ptr, sock, pos, col);
+ if (--selected_output_ct == 0)
+ break; /* stop as soon as last one is drawn */
+ }
+ }
+ }
+
+ immEnd();
}
+
+ immUnbindProgram();
+
+ GPU_disable_program_point_size();
+ glDisable(GL_BLEND);
}
static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTree *ntree, bNode *node, bNodeInstanceKey key)
{
bNodeInstanceHash *previews = CTX_data_pointer_get(C, "node_previews").data;
- bNodeSocket *sock;
rctf *rct = &node->totr;
float iconofs;
/* float socket_size = NODE_SOCKSIZE*U.dpi/72; */ /* UNUSED */
float iconbutw = 0.8f * UI_UNIT_X;
int color_id = node_get_colorid(node);
+ float color[4];
char showname[128]; /* 128 used below */
View2D *v2d = &ar->v2d;
- /* XXX hack: copy values from linked ID data where displayed as sockets */
- if (node->block)
- nodeSynchronizeID(node, false);
-
/* skip if out of view */
- if (BLI_rctf_isect(&node->totr, &ar->v2d.cur, NULL) == false) {
+ if (BLI_rctf_isect(&node->totr, &v2d->cur, NULL) == false) {
UI_block_end(C, node->block);
node->block = NULL;
return;
@@ -858,23 +889,24 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
/* shadow */
node_draw_shadow(snode, node, BASIS_RAD, 1.0f);
- /* header uses color from backdrop, but we make it opaqie */
- if (color_id == TH_NODE) {
- float col[3];
- UI_GetThemeColorShade3fv(color_id, -20, col);
- glColor4f(col[0], col[1], col[2], 1.0f);
+ if (node->flag & NODE_MUTED) {
+ UI_GetThemeColorBlendShade4fv(color_id, TH_REDALERT, 0.5f, 0, color);
+ }
+ else {
+ /* header uses color from backdrop, but we make it opaque */
+ if (color_id == TH_NODE) {
+ UI_GetThemeColorShade3fv(color_id, -20, color);
+ color[3] = 1.0f;
+ }
+ else {
+ UI_GetThemeColor4fv(color_id, color);
+ }
}
- else
- UI_ThemeColor(color_id);
-
- if (node->flag & NODE_MUTED)
- UI_ThemeColorBlend(color_id, TH_REDALERT, 0.5f);
-
glLineWidth(1.0f);
UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT);
- UI_draw_roundbox(rct->xmin, rct->ymax - NODE_DY, rct->xmax, rct->ymax, BASIS_RAD);
+ UI_draw_roundbox_aa(true, rct->xmin, rct->ymax - NODE_DY, rct->xmax, rct->ymax, BASIS_RAD, color);
/* show/hide icons */
iconofs = rct->xmax - 0.35f * U.widget_unit;
@@ -907,10 +939,12 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
}
/* title */
- if (node->flag & SELECT)
- UI_ThemeColor(TH_SELECT);
- else
- UI_ThemeColorBlendShade(TH_TEXT, color_id, 0.4f, 10);
+ if (node->flag & SELECT) {
+ UI_GetThemeColor4fv(TH_SELECT, color);
+ }
+ else {
+ UI_GetThemeColorBlendShade4fv(TH_SELECT, color_id, 0.4f, 10, color);
+ }
/* open/close entirely? */
{
@@ -925,17 +959,9 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
UI_block_emboss_set(node->block, UI_EMBOSS);
/* custom draw function for this button */
- UI_draw_icon_tri(rct->xmin + 0.5f * U.widget_unit, rct->ymax - NODE_DY / 2.0f, 'v');
+ UI_draw_icon_tri(rct->xmin + 0.5f * U.widget_unit, rct->ymax - NODE_DY / 2.0f, 'v', color);
}
- /* this isn't doing anything for the label, so commenting out */
-#if 0
- if (node->flag & SELECT)
- UI_ThemeColor(TH_TEXT_HI);
- else
- UI_ThemeColor(TH_TEXT);
-#endif
-
nodeLabel(ntree, node, showname, sizeof(showname));
//if (node->flag & NODE_MUTED)
@@ -948,55 +974,30 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
/* body */
if (!nodeIsRegistered(node))
- UI_ThemeColor4(TH_REDALERT); /* use warning color to indicate undefined types */
- else if (node->flag & NODE_CUSTOM_COLOR)
- glColor3fv(node->color);
+ UI_GetThemeColor4fv(TH_REDALERT, color); /* use warning color to indicate undefined types */
+ else if (node->flag & NODE_CUSTOM_COLOR) {
+ rgba_float_args_set(color, node->color[0], node->color[1], node->color[2], 1.0f);
+ }
else
- UI_ThemeColor4(TH_NODE);
- glEnable(GL_BLEND);
+ UI_GetThemeColor4fv(TH_NODE, color);
+
UI_draw_roundbox_corner_set(UI_CNR_BOTTOM_LEFT | UI_CNR_BOTTOM_RIGHT);
- UI_draw_roundbox(rct->xmin, rct->ymin, rct->xmax, rct->ymax - NODE_DY, BASIS_RAD);
- glDisable(GL_BLEND);
+ UI_draw_roundbox_aa(true, rct->xmin, rct->ymin, rct->xmax, rct->ymax - NODE_DY, BASIS_RAD, color);
/* outline active and selected emphasis */
if (node->flag & SELECT) {
-
- glEnable(GL_BLEND);
- glEnable(GL_LINE_SMOOTH);
-
- if (node->flag & NODE_ACTIVE)
- UI_ThemeColorShadeAlpha(TH_ACTIVE, 0, -40);
- else
- UI_ThemeColorShadeAlpha(TH_SELECT, 0, -40);
-
+ UI_GetThemeColorShadeAlpha4fv((node->flag & NODE_ACTIVE) ? TH_ACTIVE : TH_SELECT, 0, -40, color);
+
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD);
-
- glDisable(GL_LINE_SMOOTH);
- glDisable(GL_BLEND);
+ UI_draw_roundbox_aa(false, rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD, color);
}
/* disable lines */
if (node->flag & NODE_MUTED)
node_draw_mute_line(v2d, snode, node);
-
- /* socket inputs, buttons */
- for (sock = node->inputs.first; sock; sock = sock->next) {
- if (nodeSocketIsHidden(sock))
- continue;
-
- node_socket_draw(C, ntree, node, sock, NODE_SOCKSIZE, sock->flag & SELECT);
- }
-
- /* socket outputs */
- for (sock = node->outputs.first; sock; sock = sock->next) {
- if (nodeSocketIsHidden(sock))
- continue;
-
- node_socket_draw(C, ntree, node, sock, NODE_SOCKSIZE, sock->flag & SELECT);
- }
-
+ node_draw_sockets(v2d, C, ntree, node, true, false);
+
/* preview */
if (node->flag & NODE_PREVIEW && previews) {
bNodePreview *preview = BKE_node_instance_hash_lookup(previews, key);
@@ -1016,37 +1017,33 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTree *ntree, bNode *node, bNodeInstanceKey UNUSED(key))
{
- bNodeSocket *sock;
rctf *rct = &node->totr;
float dx, centy = BLI_rctf_cent_y(rct);
float hiddenrad = BLI_rctf_size_y(rct) / 2.0f;
- float socket_size = NODE_SOCKSIZE;
int color_id = node_get_colorid(node);
+ float color[4];
char showname[128]; /* 128 is used below */
+ View2D *v2d = &ar->v2d;
+ float scale;
+
+ UI_view2d_scale_get(v2d, &scale, NULL);
/* shadow */
node_draw_shadow(snode, node, hiddenrad, 1.0f);
/* body */
- UI_ThemeColor(color_id);
if (node->flag & NODE_MUTED)
- UI_ThemeColorBlend(color_id, TH_REDALERT, 0.5f);
-
- UI_draw_roundbox(rct->xmin, rct->ymin, rct->xmax, rct->ymax, hiddenrad);
+ UI_GetThemeColorBlendShade4fv(color_id, TH_REDALERT, 0.5f, 0, color);
+ else
+ UI_GetThemeColor4fv(color_id, color);
+
+ UI_draw_roundbox_aa(true, rct->xmin, rct->ymin, rct->xmax, rct->ymax, hiddenrad, color);
/* outline active and selected emphasis */
if (node->flag & SELECT) {
- glEnable(GL_BLEND);
- glEnable(GL_LINE_SMOOTH);
-
- if (node->flag & NODE_ACTIVE)
- UI_ThemeColorShadeAlpha(TH_ACTIVE, 0, -40);
- else
- UI_ThemeColorShadeAlpha(TH_SELECT, 0, -40);
- UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rct->xmin, rct->ymin, rct->xmax, rct->ymax, hiddenrad);
-
- glDisable(GL_LINE_SMOOTH);
- glDisable(GL_BLEND);
+ UI_GetThemeColorShadeAlpha4fv((node->flag & NODE_ACTIVE) ? TH_ACTIVE : TH_SELECT, 0, -40, color);
+
+ UI_draw_roundbox_aa(false, rct->xmin, rct->ymin, rct->xmax, rct->ymax, hiddenrad, color);
}
/* custom color inline */
@@ -1054,18 +1051,19 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
- glColor3fv(node->color);
- UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rct->xmin + 1, rct->ymin + 1, rct->xmax -1, rct->ymax - 1, hiddenrad);
+ UI_draw_roundbox_3fvAlpha(false, rct->xmin + 1, rct->ymin + 1, rct->xmax -1, rct->ymax - 1, hiddenrad, node->color, 1.0f);
glDisable(GL_LINE_SMOOTH);
glDisable(GL_BLEND);
}
/* title */
- if (node->flag & SELECT)
- UI_ThemeColor(TH_SELECT);
- else
- UI_ThemeColorBlendShade(TH_TEXT, color_id, 0.4f, 10);
+ if (node->flag & SELECT) {
+ UI_GetThemeColor4fv(TH_SELECT, color);
+ }
+ else {
+ UI_GetThemeColorBlendShade4fv(TH_SELECT, color_id, 0.4f, 10, color);
+ }
/* open entirely icon */
{
@@ -1080,18 +1078,13 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
UI_block_emboss_set(node->block, UI_EMBOSS);
/* custom draw function for this button */
- UI_draw_icon_tri(rct->xmin + 10.0f, centy, 'h');
+ UI_draw_icon_tri(rct->xmin + 10.0f, centy, 'h', color);
}
/* disable lines */
if (node->flag & NODE_MUTED)
node_draw_mute_line(&ar->v2d, snode, node);
-
- if (node->flag & SELECT)
- UI_ThemeColor(TH_SELECT);
- else
- UI_ThemeColor(TH_TEXT);
-
+
if (node->miniwidth > 0.0f) {
nodeLabel(ntree, node, showname, sizeof(showname));
@@ -1105,29 +1098,35 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
}
/* scale widget thing */
- UI_ThemeColorShade(color_id, -10);
+ unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformThemeColorShade(color_id, -10);
dx = 10.0f;
- fdrawline(rct->xmax - dx, centy - 4.0f, rct->xmax - dx, centy + 4.0f);
- fdrawline(rct->xmax - dx - 3.0f * snode->aspect, centy - 4.0f, rct->xmax - dx - 3.0f * snode->aspect, centy + 4.0f);
-
- UI_ThemeColorShade(color_id, +30);
+
+ immBegin(GWN_PRIM_LINES, 4);
+ immVertex2f(pos, rct->xmax - dx, centy - 4.0f);
+ immVertex2f(pos, rct->xmax - dx, centy + 4.0f);
+
+ immVertex2f(pos, rct->xmax - dx - 3.0f * snode->aspect, centy - 4.0f);
+ immVertex2f(pos, rct->xmax - dx - 3.0f * snode->aspect, centy + 4.0f);
+ immEnd();
+
+ immUniformThemeColorShade(color_id, 30);
dx -= snode->aspect;
- fdrawline(rct->xmax - dx, centy - 4.0f, rct->xmax - dx, centy + 4.0f);
- fdrawline(rct->xmax - dx - 3.0f * snode->aspect, centy - 4.0f, rct->xmax - dx - 3.0f * snode->aspect, centy + 4.0f);
- /* sockets */
- for (sock = node->inputs.first; sock; sock = sock->next) {
- if (!nodeSocketIsHidden(sock)) {
- node_socket_draw(C, ntree, node, sock, socket_size, sock->flag & SELECT);
- }
- }
-
- for (sock = node->outputs.first; sock; sock = sock->next) {
- if (!nodeSocketIsHidden(sock)) {
- node_socket_draw(C, ntree, node, sock, socket_size, sock->flag & SELECT);
- }
- }
-
+ immBegin(GWN_PRIM_LINES, 4);
+ immVertex2f(pos, rct->xmax - dx, centy - 4.0f);
+ immVertex2f(pos, rct->xmax - dx, centy + 4.0f);
+
+ immVertex2f(pos, rct->xmax - dx - 3.0f * snode->aspect, centy - 4.0f);
+ immVertex2f(pos, rct->xmax - dx - 3.0f * snode->aspect, centy + 4.0f);
+ immEnd();
+
+ immUnbindProgram();
+
+ node_draw_sockets(v2d, C, ntree, node, true, false);
+
UI_block_end(C, node->block);
UI_block_draw(C, node->block);
node->block = NULL;
@@ -1241,12 +1240,12 @@ void node_draw_nodetree(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeT
/* node lines */
glEnable(GL_BLEND);
- glEnable(GL_LINE_SMOOTH);
+ nodelink_batch_start(snode);
for (link = ntree->links.first; link; link = link->next) {
if (!nodeLinkIsHidden(link))
node_draw_link(&ar->v2d, snode, link);
}
- glDisable(GL_LINE_SMOOTH);
+ nodelink_batch_end(snode);
glDisable(GL_BLEND);
/* draw foreground nodes, last nodes in front */
@@ -1268,7 +1267,7 @@ static void draw_tree_path(SpaceNode *snode)
ED_node_tree_path_get_fixedbuf(snode, info, sizeof(info));
- UI_ThemeColor(TH_TEXT_HI);
+ UI_FontThemeColor(BLF_default(), TH_TEXT_HI);
BLF_draw_default(1.5f * UI_UNIT_X, 1.5f * UI_UNIT_Y, 0.0f, info, sizeof(info));
}
@@ -1301,12 +1300,14 @@ static void draw_group_overlay(const bContext *C, ARegion *ar)
View2D *v2d = &ar->v2d;
rctf rect = v2d->cur;
uiBlock *block;
-
+ float color[4];
+
/* shade node groups to separate them visually */
- UI_ThemeColorShadeAlpha(TH_NODE_GROUP, 0, -70);
glEnable(GL_BLEND);
+
+ UI_GetThemeColorShadeAlpha4fv(TH_NODE_GROUP, 0, -70, color);
UI_draw_roundbox_corner_set(UI_CNR_NONE);
- UI_draw_roundbox_gl_mode(GL_POLYGON, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 0);
+ UI_draw_roundbox_4fv(true, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 0, color);
glDisable(GL_BLEND);
/* set the block bounds to clip mouse events from underlying nodes */
@@ -1337,8 +1338,7 @@ void drawnodespace(const bContext *C, ARegion *ar)
ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
/* only set once */
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_MAP1_VERTEX_3);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
/* nodes */
snode_set_context(C);
@@ -1398,7 +1398,22 @@ void drawnodespace(const bContext *C, ARegion *ar)
/* backdrop */
draw_nodespace_back_pix(C, ar, snode, path->parent_key);
-
+
+ {
+ float original_proj[4][4];
+ gpuGetProjectionMatrix(original_proj);
+
+ gpuPushMatrix();
+ gpuLoadIdentity();
+
+ wmOrtho2_pixelspace(ar->winx, ar->winy);
+
+ WM_manipulatormap_draw(ar->manipulator_map, C, WM_MANIPULATORMAP_DRAWSTEP_2D);
+
+ gpuPopMatrix();
+ gpuLoadProjectionMatrix(original_proj);
+ }
+
draw_nodetree(C, ar, ntree, path->parent_key);
}
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index e38b48d4bb8..d91c330c853 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -41,7 +41,6 @@
#include "BLI_blenlib.h"
#include "BKE_context.h"
-#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_library.h"
@@ -50,6 +49,8 @@
#include "BKE_report.h"
#include "BKE_scene.h"
+#include "DEG_depsgraph.h"
+
#include "RE_engine.h"
#include "RE_pipeline.h"
@@ -123,7 +124,7 @@ static int compo_get_recalc_flags(const bContext *C)
int recalc_flags = 0;
for (win = wm->windows.first; win; win = win->next) {
- bScreen *sc = win->screen;
+ const bScreen *sc = WM_window_get_active_screen(win);
ScrArea *sa;
for (sa = sc->areabase.first; sa; sa = sa->next) {
@@ -328,11 +329,11 @@ void snode_dag_update(bContext *C, SpaceNode *snode)
if (snode->edittree != snode->nodetree) {
FOREACH_NODETREE(bmain, tntree, id) {
if (ntreeHasTree(tntree, snode->edittree))
- DAG_id_tag_update(id, 0);
+ DEG_id_tag_update(id, 0);
} FOREACH_NODETREE_END
}
- DAG_id_tag_update(snode->id, 0);
+ DEG_id_tag_update(snode->id, 0);
}
void snode_notify(bContext *C, SpaceNode *snode)
@@ -382,7 +383,6 @@ bool ED_node_is_texture(struct SpaceNode *snode)
/* called from shading buttons or header */
void ED_node_shader_default(const bContext *C, ID *id)
{
- Scene *scene = CTX_data_scene(C);
bNode *in, *out;
bNodeSocket *fromsock, *tosock, *sock;
bNodeTree *ntree;
@@ -397,14 +397,8 @@ void ED_node_shader_default(const bContext *C, ID *id)
Material *ma = (Material *)id;
ma->nodetree = ntree;
- if (BKE_scene_use_new_shading_nodes(scene)) {
- output_type = SH_NODE_OUTPUT_MATERIAL;
- shader_type = SH_NODE_BSDF_DIFFUSE;
- }
- else {
- output_type = SH_NODE_OUTPUT;
- shader_type = SH_NODE_MATERIAL;
- }
+ output_type = SH_NODE_OUTPUT_MATERIAL;
+ shader_type = SH_NODE_BSDF_PRINCIPLED;
copy_v3_v3(color, &ma->r);
strength = 0.0f;
@@ -455,18 +449,16 @@ void ED_node_shader_default(const bContext *C, ID *id)
nodeAddLink(ntree, in, fromsock, out, tosock);
/* default values */
- if (BKE_scene_use_new_shading_nodes(scene)) {
- PointerRNA sockptr;
- sock = in->inputs.first;
- RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &sockptr);
-
- RNA_float_set_array(&sockptr, "default_value", color);
+ PointerRNA sockptr;
+ sock = in->inputs.first;
+ RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &sockptr);
+
+ RNA_float_set_array(&sockptr, "default_value", color);
- if (strength != 0.0f) {
- sock = in->inputs.last;
- RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &sockptr);
- RNA_float_set(&sockptr, "default_value", strength);
- }
+ if (strength != 0.0f) {
+ sock = in->inputs.last;
+ RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &sockptr);
+ RNA_float_set(&sockptr, "default_value", strength);
}
ntreeUpdateTree(CTX_data_main(C), ntree);
@@ -545,12 +537,6 @@ void snode_set_context(const bContext *C)
bNodeTree *ntree = snode->nodetree;
ID *id = snode->id, *from = snode->from;
- /* we use this to signal warnings, when node shaders are drawn in wrong render engine */
- if (BKE_scene_use_new_shading_nodes(CTX_data_scene(C)))
- snode->flag |= SNODE_NEW_SHADERS;
- else
- snode->flag &= ~SNODE_NEW_SHADERS;
-
/* check the tree type */
if (!treetype ||
(treetype->poll && !treetype->poll(C, treetype)))
@@ -638,7 +624,7 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node)
if (node->id && ELEM(GS(node->id->name), ID_MA, ID_LA, ID_WO))
nodeClearActiveID(ntree, ID_TE);
- if (ELEM(node->type, SH_NODE_OUTPUT, SH_NODE_OUTPUT_MATERIAL,
+ if (ELEM(node->type, SH_NODE_OUTPUT_MATERIAL,
SH_NODE_OUTPUT_WORLD, SH_NODE_OUTPUT_LAMP, SH_NODE_OUTPUT_LINESTYLE))
{
bNode *tnode;
@@ -689,22 +675,6 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node)
/* addnode() doesnt link this yet... */
node->id = (ID *)BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
}
- else if (node->type == CMP_NODE_R_LAYERS) {
- Scene *scene;
-
- for (scene = bmain->scene.first; scene; scene = scene->id.next) {
- if (scene->nodetree && scene->use_nodes && ntreeHasTree(scene->nodetree, ntree)) {
- if (node->id == NULL || node->id == (ID *)scene) {
- int num_layers = BLI_listbase_count(&scene->r.layers);
- scene->r.actlay = node->custom1;
- /* Clamp the value, because it might have come from a different
- * scene which could have more render layers than new one.
- */
- scene->r.actlay = min_ff(scene->r.actlay, num_layers - 1);
- }
- }
- }
- }
else if (node->type == CMP_NODE_COMPOSITE) {
if (was_output == 0) {
bNode *tnode;
@@ -1271,7 +1241,7 @@ bool ED_node_select_check(ListBase *lb)
/* goes over all scenes, reads render layers */
-static int node_read_renderlayers_exec(bContext *C, wmOperator *UNUSED(op))
+static int node_read_viewlayers_exec(bContext *C, wmOperator *UNUSED(op))
{
Main *bmain = CTX_data_main(C);
SpaceNode *snode = CTX_wm_space_node(C);
@@ -1301,48 +1271,14 @@ static int node_read_renderlayers_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-void NODE_OT_read_renderlayers(wmOperatorType *ot)
+void NODE_OT_read_viewlayers(wmOperatorType *ot)
{
- ot->name = "Read Render Layers";
- ot->idname = "NODE_OT_read_renderlayers";
+ ot->name = "Read View Layers";
+ ot->idname = "NODE_OT_read_viewlayers";
ot->description = "Read all render layers of all used scenes";
- ot->exec = node_read_renderlayers_exec;
-
- ot->poll = composite_node_active;
-
- /* flags */
- ot->flag = 0;
-}
-
-static int node_read_fullsamplelayers_exec(bContext *C, wmOperator *UNUSED(op))
-{
- Main *bmain = CTX_data_main(C);
- SpaceNode *snode = CTX_wm_space_node(C);
- Scene *curscene = CTX_data_scene(C);
- Render *re = RE_NewSceneRender(curscene);
-
- WM_cursor_wait(1);
- RE_MergeFullSample(re, bmain, curscene, snode->nodetree);
- WM_cursor_wait(0);
-
- /* note we are careful to send the right notifier, as otherwise the
- * compositor would reexecute and overwrite the full sample result */
- WM_event_add_notifier(C, NC_SCENE | ND_COMPO_RESULT, NULL);
-
- return OPERATOR_FINISHED;
-}
-
-
-void NODE_OT_read_fullsamplelayers(wmOperatorType *ot)
-{
-
- ot->name = "Read Full Sample Layers";
- ot->idname = "NODE_OT_read_fullsamplelayers";
- ot->description = "Read all render layers of current scene, in full sample";
-
- ot->exec = node_read_fullsamplelayers_exec;
+ ot->exec = node_read_viewlayers_exec;
ot->poll = composite_node_active;
@@ -1361,13 +1297,13 @@ int node_render_changed_exec(bContext *C, wmOperator *UNUSED(op))
}
}
if (node) {
- SceneRenderLayer *srl = BLI_findlink(&sce->r.layers, node->custom1);
+ ViewLayer *view_layer = BLI_findlink(&sce->view_layers, node->custom1);
- if (srl) {
+ if (view_layer) {
PointerRNA op_ptr;
WM_operator_properties_create(&op_ptr, "RENDER_OT_render");
- RNA_string_set(&op_ptr, "layer", srl->name);
+ RNA_string_set(&op_ptr, "layer", view_layer->name);
RNA_string_set(&op_ptr, "scene", sce->id.name + 2);
/* to keep keypositions */
diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h
index 352f9e51012..1235133f8ac 100644
--- a/source/blender/editors/space_node/node_intern.h
+++ b/source/blender/editors/space_node/node_intern.h
@@ -67,13 +67,11 @@ void snode_group_offset(struct SpaceNode *snode, float *x, float *y); /* transfo
/* node_draw.c */
int node_get_colorid(struct bNode *node);
-void node_socket_draw(
- const struct bContext *C, struct bNodeTree *ntree, struct bNode *node,
- struct bNodeSocket *sock, float size, bool highlight);
int node_get_resize_cursor(int directions);
void node_draw_shadow(struct SpaceNode *snode, struct bNode *node, float radius, float alpha);
void node_draw_default(const struct bContext *C, struct ARegion *ar, struct SpaceNode *snode,
struct bNodeTree *ntree, struct bNode *node, bNodeInstanceKey key);
+void node_draw_sockets(struct View2D *v2d, const struct bContext *C, struct bNodeTree *ntree, struct bNode *node, bool draw_outputs, bool select_all);
void node_update_default(const struct bContext *C, struct bNodeTree *ntree, struct bNode *node);
int node_select_area_default(struct bNode *node, int x, int y);
int node_tweak_area_default(struct bNode *node, int x, int y);
@@ -132,8 +130,11 @@ void NODE_OT_backimage_fit(struct wmOperatorType *ot);
void NODE_OT_backimage_sample(struct wmOperatorType *ot);
/* drawnode.c */
+void nodelink_batch_start(struct SpaceNode *snode);
+void nodelink_batch_end(struct SpaceNode *snode);
+
void node_draw_link(struct View2D *v2d, struct SpaceNode *snode, struct bNodeLink *link);
-void node_draw_link_bezier(struct View2D *v2d, struct SpaceNode *snode, struct bNodeLink *link, int th_col1, bool do_shaded, int th_col2, bool do_triple, int th_col3);
+void node_draw_link_bezier(struct View2D *v2d, struct SpaceNode *snode, struct bNodeLink *link, int th_col1, int th_col2, int th_col3);
bool node_link_bezier_points(struct View2D *v2d, struct SpaceNode *snode, struct bNodeLink *link, float coord_array[][2], int resol);
// void node_draw_link_straight(View2D *v2d, SpaceNode *snode, bNodeLink *link, int th_col1, int do_shaded, int th_col2, int do_triple, int th_col3 );
void draw_nodespace_back_pix(const struct bContext *C, struct ARegion *ar, struct SpaceNode *snode, bNodeInstanceKey parent_key);
@@ -199,7 +200,7 @@ void NODE_OT_options_toggle(struct wmOperatorType *ot);
void NODE_OT_node_copy_color(struct wmOperatorType *ot);
void NODE_OT_read_fullsamplelayers(struct wmOperatorType *ot);
-void NODE_OT_read_renderlayers(struct wmOperatorType *ot);
+void NODE_OT_read_viewlayers(struct wmOperatorType *ot);
void NODE_OT_render_changed(struct wmOperatorType *ot);
void NODE_OT_output_file_add_socket(struct wmOperatorType *ot);
@@ -221,6 +222,13 @@ void NODE_OT_shader_script_update(struct wmOperatorType *ot);
void NODE_OT_viewer_border(struct wmOperatorType *ot);
void NODE_OT_clear_viewer_border(struct wmOperatorType *ot);
+/* node_widgets.c */
+void NODE_WGT_backdrop_transform(struct wmManipulatorGroupType *wgt);
+void NODE_WGT_backdrop_crop(struct wmManipulatorGroupType *wgt);
+void NODE_WGT_backdrop_sun_beams(struct wmManipulatorGroupType *wgt);
+void NODE_WGT_backdrop_corner_pin(struct wmManipulatorGroupType *wgt);
+
+
extern const char *node_context_dir[];
// XXXXXX
diff --git a/source/blender/editors/space_node/node_manipulators.c b/source/blender/editors/space_node/node_manipulators.c
new file mode 100644
index 00000000000..73b0f44b043
--- /dev/null
+++ b/source/blender/editors/space_node/node_manipulators.c
@@ -0,0 +1,616 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_node/node_manipulators.c
+ * \ingroup spnode
+ */
+
+#include <math.h>
+
+#include "BLI_utildefines.h"
+#include "BLI_math_matrix.h"
+#include "BLI_math_vector.h"
+#include "BLI_rect.h"
+
+#include "BKE_context.h"
+#include "BKE_image.h"
+
+#include "ED_screen.h"
+#include "ED_manipulator_library.h"
+
+#include "IMB_imbuf_types.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "RNA_access.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "node_intern.h"
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Local Utilities
+ * \{ */
+
+static void node_manipulator_calc_matrix_space(
+ const SpaceNode *snode, const ARegion *ar, float matrix_space[4][4])
+{
+ unit_m4(matrix_space);
+ mul_v3_fl(matrix_space[0], snode->zoom);
+ mul_v3_fl(matrix_space[1], snode->zoom);
+ matrix_space[3][0] = (ar->winx / 2) + snode->xof;
+ matrix_space[3][1] = (ar->winy / 2) + snode->yof;
+}
+
+static void node_manipulator_calc_matrix_space_with_image_dims(
+ const SpaceNode *snode, const ARegion *ar, const float image_dims[2], float matrix_space[4][4])
+{
+ unit_m4(matrix_space);
+ mul_v3_fl(matrix_space[0], snode->zoom * image_dims[0]);
+ mul_v3_fl(matrix_space[1], snode->zoom * image_dims[1]);
+ matrix_space[3][0] = ((ar->winx / 2) + snode->xof) - ((image_dims[0] / 2.0f) * snode->zoom);
+ matrix_space[3][1] = ((ar->winy / 2) + snode->yof) - ((image_dims[1] / 2.0f) * snode->zoom);
+}
+
+/** \} */
+
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Backdrop Manipulator
+ * \{ */
+
+static void manipulator_node_backdrop_prop_matrix_get(
+ const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop,
+ void *value_p)
+{
+ float (*matrix)[4] = value_p;
+ BLI_assert(mpr_prop->type->array_length == 16);
+ const SpaceNode *snode = mpr_prop->custom_func.user_data;
+ matrix[0][0] = snode->zoom;
+ matrix[1][1] = snode->zoom;
+ matrix[3][0] = snode->xof;
+ matrix[3][1] = snode->yof;
+}
+
+static void manipulator_node_backdrop_prop_matrix_set(
+ const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop,
+ const void *value_p)
+{
+ const float (*matrix)[4] = value_p;
+ BLI_assert(mpr_prop->type->array_length == 16);
+ SpaceNode *snode = mpr_prop->custom_func.user_data;
+ snode->zoom = matrix[0][0];
+ snode->zoom = matrix[1][1];
+ snode->xof = matrix[3][0];
+ snode->yof = matrix[3][1];
+}
+
+static bool WIDGETGROUP_node_transform_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt))
+{
+ SpaceNode *snode = CTX_wm_space_node(C);
+
+ if ((snode->flag & SNODE_BACKDRAW) == 0) {
+ return false;
+ }
+
+ if (snode && snode->edittree && snode->edittree->type == NTREE_COMPOSIT) {
+ bNode *node = nodeGetActive(snode->edittree);
+
+ if (node && ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static void WIDGETGROUP_node_transform_setup(const bContext *UNUSED(C), wmManipulatorGroup *mgroup)
+{
+ wmManipulatorWrapper *wwrapper = MEM_mallocN(sizeof(wmManipulatorWrapper), __func__);
+
+ wwrapper->manipulator = WM_manipulator_new("MANIPULATOR_WT_cage_2d", mgroup, NULL);
+
+ RNA_enum_set(wwrapper->manipulator->ptr, "transform",
+ ED_MANIPULATOR_CAGE2D_XFORM_FLAG_TRANSLATE | ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE_UNIFORM);
+
+ mgroup->customdata = wwrapper;
+}
+
+static void WIDGETGROUP_node_transform_refresh(const bContext *C, wmManipulatorGroup *mgroup)
+{
+ wmManipulator *cage = ((wmManipulatorWrapper *)mgroup->customdata)->manipulator;
+ const ARegion *ar = CTX_wm_region(C);
+ /* center is always at the origin */
+ const float origin[3] = {ar->winx / 2, ar->winy / 2};
+
+ void *lock;
+ Image *ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
+
+ if (ibuf) {
+ const float dims[2] = {
+ (ibuf->x > 0) ? ibuf->x : 64.0f,
+ (ibuf->y > 0) ? ibuf->y : 64.0f,
+ };
+
+ RNA_float_set_array(cage->ptr, "dimensions", dims);
+ WM_manipulator_set_matrix_location(cage, origin);
+ WM_manipulator_set_flag(cage, WM_MANIPULATOR_HIDDEN, false);
+
+ /* need to set property here for undo. TODO would prefer to do this in _init */
+ SpaceNode *snode = CTX_wm_space_node(C);
+#if 0
+ PointerRNA nodeptr;
+ RNA_pointer_create(snode->id, &RNA_SpaceNodeEditor, snode, &nodeptr);
+ WM_manipulator_target_property_def_rna(cage, "offset", &nodeptr, "backdrop_offset", -1);
+ WM_manipulator_target_property_def_rna(cage, "scale", &nodeptr, "backdrop_zoom", -1);
+#endif
+
+ WM_manipulator_target_property_def_func(
+ cage, "matrix",
+ &(const struct wmManipulatorPropertyFnParams) {
+ .value_get_fn = manipulator_node_backdrop_prop_matrix_get,
+ .value_set_fn = manipulator_node_backdrop_prop_matrix_set,
+ .range_get_fn = NULL,
+ .user_data = snode,
+ });
+ }
+ else {
+ WM_manipulator_set_flag(cage, WM_MANIPULATOR_HIDDEN, true);
+ }
+
+ BKE_image_release_ibuf(ima, ibuf, lock);
+}
+
+void NODE_WGT_backdrop_transform(wmManipulatorGroupType *wgt)
+{
+ wgt->name = "Backdrop Transform Widget";
+ wgt->idname = "NODE_WGT_backdrop_transform";
+
+ wgt->flag |= WM_MANIPULATORGROUPTYPE_PERSISTENT;
+
+ wgt->poll = WIDGETGROUP_node_transform_poll;
+ wgt->setup = WIDGETGROUP_node_transform_setup;
+ wgt->refresh = WIDGETGROUP_node_transform_refresh;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+
+/** \name Crop Manipulator
+ * \{ */
+
+struct NodeCropWidgetGroup {
+ wmManipulator *border;
+
+ struct {
+ float dims[2];
+ } state;
+
+ struct {
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ bContext *context;
+ } update_data;
+};
+
+static void manipulator_node_crop_update(struct NodeCropWidgetGroup *crop_group)
+{
+ RNA_property_update(crop_group->update_data.context, &crop_group->update_data.ptr, crop_group->update_data.prop);
+}
+
+static void two_xy_to_rect(const NodeTwoXYs *nxy, rctf *rect, const float dims[2], bool is_relative)
+{
+ if (is_relative) {
+ rect->xmin = nxy->fac_x1;
+ rect->xmax = nxy->fac_x2;
+ rect->ymin = nxy->fac_y1;
+ rect->ymax = nxy->fac_y2;
+ }
+ else {
+ rect->xmin = nxy->x1 / dims[0];
+ rect->xmax = nxy->x2 / dims[0];
+ rect->ymin = nxy->y1 / dims[1];
+ rect->ymax = nxy->y2 / dims[1];
+ }
+}
+
+static void two_xy_from_rect(NodeTwoXYs *nxy, const rctf *rect, const float dims[2], bool is_relative)
+{
+ if (is_relative) {
+ nxy->fac_x1 = rect->xmin;
+ nxy->fac_x2 = rect->xmax;
+ nxy->fac_y1 = rect->ymin;
+ nxy->fac_y2 = rect->ymax;
+ }
+ else {
+ nxy->x1 = rect->xmin * dims[0];
+ nxy->x2 = rect->xmax * dims[0];
+ nxy->y1 = rect->ymin * dims[1];
+ nxy->y2 = rect->ymax * dims[1];
+ }
+}
+
+/* scale callbacks */
+static void manipulator_node_crop_prop_matrix_get(
+ const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
+ void *value_p)
+{
+ float (*matrix)[4] = value_p;
+ BLI_assert(mpr_prop->type->array_length == 16);
+ struct NodeCropWidgetGroup *crop_group = mpr->parent_mgroup->customdata;
+ const float *dims = crop_group->state.dims;
+ const bNode *node = mpr_prop->custom_func.user_data;
+ const NodeTwoXYs *nxy = node->storage;
+ bool is_relative = (bool)node->custom2;
+ rctf rct;
+ two_xy_to_rect(nxy, &rct, dims, is_relative);
+ matrix[0][0] = BLI_rctf_size_x(&rct);
+ matrix[1][1] = BLI_rctf_size_y(&rct);
+ matrix[3][0] = (BLI_rctf_cent_x(&rct) - 0.5f) * dims[0];
+ matrix[3][1] = (BLI_rctf_cent_y(&rct) - 0.5f) * dims[1];
+}
+
+static void manipulator_node_crop_prop_matrix_set(
+ const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
+ const void *value_p)
+{
+ const float (*matrix)[4] = value_p;
+ BLI_assert(mpr_prop->type->array_length == 16);
+ struct NodeCropWidgetGroup *crop_group = mpr->parent_mgroup->customdata;
+ const float *dims = crop_group->state.dims;
+ bNode *node = mpr_prop->custom_func.user_data;
+ NodeTwoXYs *nxy = node->storage;
+ bool is_relative = (bool)node->custom2;
+ rctf rct;
+ two_xy_to_rect(nxy, &rct, dims, is_relative);
+ BLI_rctf_resize(&rct, matrix[0][0], matrix[1][1]);
+ BLI_rctf_recenter(&rct, (matrix[3][0] / dims[0]) + 0.5f, (matrix[3][1] / dims[1]) + 0.5f);
+ BLI_rctf_isect(&(rctf){.xmin = 0, .ymin = 0, .xmax = 1, .ymax = 1}, &rct, &rct);
+ two_xy_from_rect(nxy, &rct, dims, is_relative);
+ manipulator_node_crop_update(crop_group);
+}
+
+static bool WIDGETGROUP_node_crop_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt))
+{
+ SpaceNode *snode = CTX_wm_space_node(C);
+
+ if ((snode->flag & SNODE_BACKDRAW) == 0) {
+ return false;
+ }
+
+ if (snode && snode->edittree && snode->edittree->type == NTREE_COMPOSIT) {
+ bNode *node = nodeGetActive(snode->edittree);
+
+ if (node && ELEM(node->type, CMP_NODE_CROP)) {
+ /* ignore 'use_crop_size', we can't usefully edit the crop in this case. */
+ if ((node->custom1 & (0 << 1)) == 0) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+static void WIDGETGROUP_node_crop_setup(const bContext *UNUSED(C), wmManipulatorGroup *mgroup)
+{
+ struct NodeCropWidgetGroup *crop_group = MEM_mallocN(sizeof(struct NodeCropWidgetGroup), __func__);
+
+ crop_group->border = WM_manipulator_new("MANIPULATOR_WT_cage_2d", mgroup, NULL);
+
+ RNA_enum_set(crop_group->border->ptr, "transform",
+ ED_MANIPULATOR_CAGE2D_XFORM_FLAG_TRANSLATE | ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE);
+
+ mgroup->customdata = crop_group;
+}
+
+static void WIDGETGROUP_node_crop_draw_prepare(const bContext *C, wmManipulatorGroup *mgroup)
+{
+ ARegion *ar = CTX_wm_region(C);
+ wmManipulator *mpr = mgroup->manipulators.first;
+
+ SpaceNode *snode = CTX_wm_space_node(C);
+
+ node_manipulator_calc_matrix_space(snode, ar, mpr->matrix_space);
+}
+
+static void WIDGETGROUP_node_crop_refresh(const bContext *C, wmManipulatorGroup *mgroup)
+{
+ struct NodeCropWidgetGroup *crop_group = mgroup->customdata;
+ wmManipulator *mpr = crop_group->border;
+
+ void *lock;
+ Image *ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
+
+ if (ibuf) {
+ crop_group->state.dims[0] = (ibuf->x > 0) ? ibuf->x : 64.0f;
+ crop_group->state.dims[1] = (ibuf->y > 0) ? ibuf->y : 64.0f;
+
+ RNA_float_set_array(mpr->ptr, "dimensions", crop_group->state.dims);
+ WM_manipulator_set_flag(mpr, WM_MANIPULATOR_HIDDEN, false);
+
+ SpaceNode *snode = CTX_wm_space_node(C);
+ bNode *node = nodeGetActive(snode->edittree);
+
+ crop_group->update_data.context = (bContext *)C;
+ RNA_pointer_create((ID *)snode->edittree, &RNA_CompositorNodeCrop, node, &crop_group->update_data.ptr);
+ crop_group->update_data.prop = RNA_struct_find_property(&crop_group->update_data.ptr, "relative");
+
+ WM_manipulator_target_property_def_func(
+ mpr, "matrix",
+ &(const struct wmManipulatorPropertyFnParams) {
+ .value_get_fn = manipulator_node_crop_prop_matrix_get,
+ .value_set_fn = manipulator_node_crop_prop_matrix_set,
+ .range_get_fn = NULL,
+ .user_data = node,
+ });
+ }
+ else {
+ WM_manipulator_set_flag(mpr, WM_MANIPULATOR_HIDDEN, true);
+ }
+
+ BKE_image_release_ibuf(ima, ibuf, lock);
+}
+
+void NODE_WGT_backdrop_crop(wmManipulatorGroupType *wgt)
+{
+ wgt->name = "Backdrop Crop Widget";
+ wgt->idname = "NODE_WGT_backdrop_crop";
+
+ wgt->flag |= WM_MANIPULATORGROUPTYPE_PERSISTENT;
+
+ wgt->poll = WIDGETGROUP_node_crop_poll;
+ wgt->setup = WIDGETGROUP_node_crop_setup;
+ wgt->draw_prepare = WIDGETGROUP_node_crop_draw_prepare;
+ wgt->refresh = WIDGETGROUP_node_crop_refresh;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+
+/** \name Sun Beams
+ * \{ */
+
+struct NodeSunBeamsWidgetGroup {
+ wmManipulator *manipulator;
+
+ struct {
+ float dims[2];
+ } state;
+};
+
+static bool WIDGETGROUP_node_sbeam_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt))
+{
+ SpaceNode *snode = CTX_wm_space_node(C);
+
+ if ((snode->flag & SNODE_BACKDRAW) == 0) {
+ return false;
+ }
+
+ if (snode && snode->edittree && snode->edittree->type == NTREE_COMPOSIT) {
+ bNode *node = nodeGetActive(snode->edittree);
+
+ if (node && ELEM(node->type, CMP_NODE_SUNBEAMS)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static void WIDGETGROUP_node_sbeam_setup(const bContext *UNUSED(C), wmManipulatorGroup *mgroup)
+{
+ struct NodeSunBeamsWidgetGroup *sbeam_group = MEM_mallocN(sizeof(struct NodeSunBeamsWidgetGroup), __func__);
+
+ sbeam_group->manipulator = WM_manipulator_new("MANIPULATOR_WT_grab_3d", mgroup, NULL);
+ wmManipulator *mpr = sbeam_group->manipulator;
+
+ RNA_enum_set(mpr->ptr, "draw_style", ED_MANIPULATOR_GRAB_STYLE_CROSS_2D);
+
+ mpr->scale_basis = 0.05f;
+
+ mgroup->customdata = sbeam_group;
+}
+
+static void WIDGETGROUP_node_sbeam_draw_prepare(const bContext *C, wmManipulatorGroup *mgroup)
+{
+ struct NodeSunBeamsWidgetGroup *sbeam_group = mgroup->customdata;
+ ARegion *ar = CTX_wm_region(C);
+ wmManipulator *mpr = mgroup->manipulators.first;
+
+ SpaceNode *snode = CTX_wm_space_node(C);
+
+ node_manipulator_calc_matrix_space_with_image_dims(snode, ar, sbeam_group->state.dims, mpr->matrix_space);
+}
+
+static void WIDGETGROUP_node_sbeam_refresh(const bContext *C, wmManipulatorGroup *mgroup)
+{
+ struct NodeSunBeamsWidgetGroup *sbeam_group = mgroup->customdata;
+ wmManipulator *mpr = sbeam_group->manipulator;
+
+ void *lock;
+ Image *ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
+
+ if (ibuf) {
+ sbeam_group->state.dims[0] = (ibuf->x > 0) ? ibuf->x : 64.0f;
+ sbeam_group->state.dims[1] = (ibuf->y > 0) ? ibuf->y : 64.0f;
+
+ SpaceNode *snode = CTX_wm_space_node(C);
+ bNode *node = nodeGetActive(snode->edittree);
+
+ /* need to set property here for undo. TODO would prefer to do this in _init */
+ PointerRNA nodeptr;
+ RNA_pointer_create((ID *)snode->edittree, &RNA_CompositorNodeSunBeams, node, &nodeptr);
+ WM_manipulator_target_property_def_rna(mpr, "offset", &nodeptr, "source", -1);
+
+ WM_manipulator_set_flag(mpr, WM_MANIPULATOR_DRAW_MODAL, true);
+ }
+ else {
+ WM_manipulator_set_flag(mpr, WM_MANIPULATOR_HIDDEN, true);
+ }
+
+ BKE_image_release_ibuf(ima, ibuf, lock);
+}
+
+void NODE_WGT_backdrop_sun_beams(wmManipulatorGroupType *wgt)
+{
+ wgt->name = "Sun Beams Widget";
+ wgt->idname = "NODE_WGT_sbeam";
+
+ wgt->flag |= WM_MANIPULATORGROUPTYPE_PERSISTENT;
+
+ wgt->poll = WIDGETGROUP_node_sbeam_poll;
+ wgt->setup = WIDGETGROUP_node_sbeam_setup;
+ wgt->draw_prepare = WIDGETGROUP_node_sbeam_draw_prepare;
+ wgt->refresh = WIDGETGROUP_node_sbeam_refresh;
+}
+
+/** \} */
+
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Corner Pin
+ * \{ */
+
+struct NodeCornerPinWidgetGroup {
+ wmManipulator *manipulators[4];
+
+ struct {
+ float dims[2];
+ } state;
+};
+
+static bool WIDGETGROUP_node_corner_pin_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt))
+{
+ SpaceNode *snode = CTX_wm_space_node(C);
+
+ if ((snode->flag & SNODE_BACKDRAW) == 0) {
+ return false;
+ }
+
+ if (snode && snode->edittree && snode->edittree->type == NTREE_COMPOSIT) {
+ bNode *node = nodeGetActive(snode->edittree);
+
+ if (node && ELEM(node->type, CMP_NODE_CORNERPIN)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static void WIDGETGROUP_node_corner_pin_setup(const bContext *UNUSED(C), wmManipulatorGroup *mgroup)
+{
+ struct NodeCornerPinWidgetGroup *cpin_group = MEM_mallocN(sizeof(struct NodeCornerPinWidgetGroup), __func__);
+ const wmManipulatorType *wt_grab_3d = WM_manipulatortype_find("MANIPULATOR_WT_grab_3d", false);
+
+ for (int i = 0; i < 4; i++) {
+ cpin_group->manipulators[i] = WM_manipulator_new_ptr(wt_grab_3d, mgroup, NULL);
+ wmManipulator *mpr = cpin_group->manipulators[i];
+
+ RNA_enum_set(mpr->ptr, "draw_style", ED_MANIPULATOR_GRAB_STYLE_CROSS_2D);
+
+ mpr->scale_basis = 0.01f;
+ }
+
+ mgroup->customdata = cpin_group;
+}
+
+static void WIDGETGROUP_node_corner_pin_draw_prepare(const bContext *C, wmManipulatorGroup *mgroup)
+{
+ struct NodeCornerPinWidgetGroup *cpin_group = mgroup->customdata;
+ ARegion *ar = CTX_wm_region(C);
+
+ SpaceNode *snode = CTX_wm_space_node(C);
+
+ float matrix_space[4][4];
+ node_manipulator_calc_matrix_space_with_image_dims(snode, ar, cpin_group->state.dims, matrix_space);
+
+ for (int i = 0; i < 4; i++) {
+ wmManipulator *mpr = cpin_group->manipulators[i];
+ copy_m4_m4(mpr->matrix_space, matrix_space);
+ }
+}
+
+static void WIDGETGROUP_node_corner_pin_refresh(const bContext *C, wmManipulatorGroup *mgroup)
+{
+ struct NodeCornerPinWidgetGroup *cpin_group = mgroup->customdata;
+
+ void *lock;
+ Image *ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
+
+ if (ibuf) {
+ cpin_group->state.dims[0] = (ibuf->x > 0) ? ibuf->x : 64.0f;
+ cpin_group->state.dims[1] = (ibuf->y > 0) ? ibuf->y : 64.0f;
+
+ SpaceNode *snode = CTX_wm_space_node(C);
+ bNode *node = nodeGetActive(snode->edittree);
+
+ /* need to set property here for undo. TODO would prefer to do this in _init */
+ int i = 0;
+ for (bNodeSocket *sock = node->inputs.first; sock && i < 4; sock = sock->next) {
+ if (sock->type == SOCK_VECTOR) {
+ wmManipulator *mpr = cpin_group->manipulators[i++];
+
+ PointerRNA sockptr;
+ RNA_pointer_create((ID *)snode->edittree, &RNA_NodeSocket, sock, &sockptr);
+ WM_manipulator_target_property_def_rna(mpr, "offset", &sockptr, "default_value", -1);
+
+ WM_manipulator_set_flag(mpr, WM_MANIPULATOR_DRAW_MODAL, true);
+ }
+ }
+ }
+ else {
+ for (int i = 0; i < 4; i++) {
+ wmManipulator *mpr = cpin_group->manipulators[i];
+ WM_manipulator_set_flag(mpr, WM_MANIPULATOR_HIDDEN, true);
+ }
+ }
+
+ BKE_image_release_ibuf(ima, ibuf, lock);
+}
+
+void NODE_WGT_backdrop_corner_pin(wmManipulatorGroupType *wgt)
+{
+ wgt->name = "Corner Pin Widget";
+ wgt->idname = "NODE_WGT_backdrop_corner_pin";
+
+ wgt->flag |= WM_MANIPULATORGROUPTYPE_PERSISTENT;
+
+ wgt->poll = WIDGETGROUP_node_corner_pin_poll;
+ wgt->setup = WIDGETGROUP_node_corner_pin_setup;
+ wgt->draw_prepare = WIDGETGROUP_node_corner_pin_draw_prepare;
+ wgt->refresh = WIDGETGROUP_node_corner_pin_refresh;
+}
+
+/** \} */
diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c
index 5118d52efc4..c9c29212f02 100644
--- a/source/blender/editors/space_node/node_ops.c
+++ b/source/blender/editors/space_node/node_ops.c
@@ -94,8 +94,7 @@ void node_operatortypes(void)
WM_operatortype_append(NODE_OT_insert_offset);
- WM_operatortype_append(NODE_OT_read_renderlayers);
- WM_operatortype_append(NODE_OT_read_fullsamplelayers);
+ WM_operatortype_append(NODE_OT_read_viewlayers);
WM_operatortype_append(NODE_OT_render_changed);
WM_operatortype_append(NODE_OT_backimage_move);
@@ -335,8 +334,7 @@ void node_keymap(struct wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "NODE_OT_group_edit", TABKEY, KM_PRESS, KM_CTRL, 0);
RNA_boolean_set(kmi->ptr, "exit", true);
- WM_keymap_add_item(keymap, "NODE_OT_read_renderlayers", RKEY, KM_PRESS, KM_CTRL, 0);
- WM_keymap_add_item(keymap, "NODE_OT_read_fullsamplelayers", RKEY, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "NODE_OT_read_viewlayers", RKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "NODE_OT_render_changed", ZKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "NODE_OT_clipboard_copy", CKEY, KM_PRESS, KM_CTRL, 0);
diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c
index fcfde6f87bf..5f48b7d7a0f 100644
--- a/source/blender/editors/space_node/node_templates.c
+++ b/source/blender/editors/space_node/node_templates.c
@@ -448,10 +448,7 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname)
int compatibility = 0;
if (ntree->type == NTREE_SHADER) {
- if (BKE_scene_use_new_shading_nodes(arg->scene))
- compatibility = NODE_NEW_SHADING;
- else
- compatibility = NODE_OLD_SHADING;
+ compatibility = NODE_NEW_SHADING;
}
/* generate array of node types sorted by UI name */
diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index 2267316d257..3b24500d044 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -49,13 +49,16 @@
#include "ED_node.h"
#include "ED_render.h"
#include "ED_screen.h"
-#include "WM_api.h"
-#include "WM_types.h"
#include "UI_resources.h"
#include "UI_view2d.h"
#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
#include "node_intern.h" /* own include */
@@ -290,7 +293,7 @@ ARegion *node_has_tools_region(ScrArea *sa)
/* ******************** default callbacks for node space ***************** */
-static SpaceLink *node_new(const bContext *UNUSED(C))
+static SpaceLink *node_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
{
ARegion *ar;
SpaceNode *snode;
@@ -316,7 +319,7 @@ static SpaceLink *node_new(const bContext *UNUSED(C))
BLI_addtail(&snode->regionbase, ar);
ar->regiontype = RGN_TYPE_HEADER;
- ar->alignment = RGN_ALIGN_BOTTOM;
+ ar->alignment = RGN_ALIGN_TOP;
/* buttons/list view */
ar = MEM_callocN(sizeof(ARegion), "buttons for node");
@@ -381,12 +384,13 @@ static void node_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa))
}
-static void node_area_listener(bScreen *sc, ScrArea *sa, wmNotifier *wmn)
+static void node_area_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, Scene *UNUSED(scene),
+ WorkSpace *UNUSED(workspace))
{
/* note, ED_area_tag_refresh will re-execute compositor */
SpaceNode *snode = sa->spacedata.first;
/* shaderfrom is only used for new shading nodes, otherwise all shaders are from objects */
- short shader_type = BKE_scene_use_new_shading_nodes(sc->scene) ? snode->shaderfrom : SNODE_SHADER_OBJECT;
+ short shader_type = snode->shaderfrom;
/* preview renders */
switch (wmn->category) {
@@ -643,6 +647,14 @@ static void node_main_region_init(wmWindowManager *wm, ARegion *ar)
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy);
+ /* manipulators stay in the background for now - quick patchjob to make sure nodes themselves work */
+ if (ar->manipulator_map == NULL) {
+ ar->manipulator_map = WM_manipulatormap_new_from_type(
+ &(const struct wmManipulatorMapType_Params){SPACE_NODE, RGN_TYPE_WINDOW});
+ }
+
+ WM_manipulatormap_add_handlers(ar, ar->manipulator_map);
+
/* own keymaps */
keymap = WM_keymap_find(wm->defaultconf, "Node Generic", SPACE_NODE, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
@@ -737,18 +749,32 @@ static void node_header_region_draw(const bContext *C, ARegion *ar)
}
/* used for header + main region */
-static void node_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void node_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
+ wmManipulatorMap *mmap = ar->manipulator_map;
+
/* context changes */
switch (wmn->category) {
case NC_SPACE:
- if (wmn->data == ND_SPACE_NODE)
- ED_region_tag_redraw(ar);
+ switch (wmn->data) {
+ case ND_SPACE_NODE:
+ ED_region_tag_redraw(ar);
+ break;
+ case ND_SPACE_NODE_VIEW:
+ WM_manipulatormap_tag_refresh(mmap);
+ break;
+ }
break;
case NC_SCREEN:
+ if (wmn->data == ND_LAYOUTSET || wmn->action == NA_EDITED) {
+ WM_manipulatormap_tag_refresh(mmap);
+ }
switch (wmn->data) {
case ND_SCREENCAST:
case ND_ANIMPLAY:
+ case ND_LAYER:
ED_region_tag_redraw(ar);
break;
}
@@ -758,10 +784,20 @@ static void node_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegi
ED_region_tag_redraw(ar);
break;
case NC_SCENE:
+ ED_region_tag_redraw(ar);
+ if (wmn->data == ND_RENDER_RESULT) {
+ WM_manipulatormap_tag_refresh(mmap);
+ }
+ break;
+ case NC_NODE:
+ ED_region_tag_redraw(ar);
+ if (ELEM(wmn->action, NA_EDITED, NA_SELECTED)) {
+ WM_manipulatormap_tag_refresh(mmap);
+ }
+ break;
case NC_MATERIAL:
case NC_TEXTURE:
case NC_WORLD:
- case NC_NODE:
case NC_LINESTYLE:
ED_region_tag_redraw(ar);
break;
@@ -826,6 +862,17 @@ static int node_context(const bContext *C, const char *member, bContextDataResul
return 0;
}
+static void node_widgets(void)
+{
+ /* create the widgetmap for the area here */
+ wmManipulatorMapType *mmap_type = WM_manipulatormaptype_ensure(
+ &(const struct wmManipulatorMapType_Params){SPACE_NODE, RGN_TYPE_WINDOW});
+ WM_manipulatorgrouptype_append_and_link(mmap_type, NODE_WGT_backdrop_transform);
+ WM_manipulatorgrouptype_append_and_link(mmap_type, NODE_WGT_backdrop_crop);
+ WM_manipulatorgrouptype_append_and_link(mmap_type, NODE_WGT_backdrop_sun_beams);
+ WM_manipulatorgrouptype_append_and_link(mmap_type, NODE_WGT_backdrop_corner_pin);
+}
+
static void node_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID *new_id)
{
SpaceNode *snode = (SpaceNode *)slink;
@@ -897,6 +944,32 @@ static void node_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID
}
}
+
+static int node_space_subtype_get(ScrArea *sa)
+{
+ SpaceNode *snode = sa->spacedata.first;
+ return rna_node_tree_idname_to_enum(snode->tree_idname);
+}
+
+static void node_space_subtype_set(ScrArea *sa, int value)
+{
+ SpaceNode *snode = sa->spacedata.first;
+ ED_node_set_tree_type(snode, rna_node_tree_type_from_enum(value));
+}
+
+static void node_space_subtype_item_extend(
+ bContext *C, EnumPropertyItem **item, int *totitem)
+{
+ bool free;
+ const EnumPropertyItem *item_src = RNA_enum_node_tree_types_itemf_impl(C, &free);
+ for (const EnumPropertyItem *item_iter = item_src; item_iter->identifier; item_iter++) {
+ RNA_enum_item_add(item, totitem, item_iter);
+ }
+ if (free) {
+ MEM_freeN((void *)item_src);
+ }
+}
+
/* only called once, from space/spacetypes.c */
void ED_spacetype_node(void)
{
@@ -916,8 +989,13 @@ void ED_spacetype_node(void)
st->refresh = node_area_refresh;
st->context = node_context;
st->dropboxes = node_dropboxes;
+ st->manipulators = node_widgets;
st->id_remap = node_id_remap;
+ st->space_subtype_item_extend = node_space_subtype_item_extend;
+ st->space_subtype_get = node_space_subtype_get;
+ st->space_subtype_set = node_space_subtype_set;
+
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype node region");
art->regionid = RGN_TYPE_WINDOW;