diff options
author | Mike Erwin <significant.bit@gmail.com> | 2016-10-15 09:49:00 +0300 |
---|---|---|
committer | Mike Erwin <significant.bit@gmail.com> | 2016-10-15 09:49:00 +0300 |
commit | 9632ca0a13b415a83572378862a44047e0a362e0 (patch) | |
tree | 7ef60bcf388968bd4250d0acf42d4d4f2ea8e91a /source/blender/editors/space_node | |
parent | 2df27995f9226245c29007c3dd2eca61cb31fc69 (diff) |
OpenGL: draw node sockets more efficiently
1 or 2 draw calls per node instead of 1 per socket (inputs + outputs).
Rearranged draw order so we set uniforms less frequently.
Some style & dead code cleanup.
Part of T49043
Diffstat (limited to 'source/blender/editors/space_node')
-rw-r--r-- | source/blender/editors/space_node/drawnode.c | 64 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_draw.c | 228 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_intern.h | 3 |
3 files changed, 124 insertions, 171 deletions
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 97c68c84e3e..774bc0661cc 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -84,49 +84,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) @@ -584,13 +541,8 @@ 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; - View2D *v2d = &ar->v2d; - float xscale, yscale; - - UI_view2d_scale_get(v2d, &xscale, &yscale); #if 0 /* UNUSED */ float size = NODE_REROUTE_SIZE; @@ -644,21 +596,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! */ - unsigned pos = add_attrib(immVertexFormat(), "pos", GL_FLOAT, 2, KEEP_FLOAT); - - glEnable(GL_BLEND); - GPU_enable_program_point_size(); - - immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_SMOOTH); - - for (sock = node->inputs.first; sock; sock = sock->next) { - node_socket_circle_draw(C, ntree, node, sock, NODE_SOCKSIZE * xscale, (sock->flag & SELECT) || (node->flag & SELECT), pos); - } - - immUnbindProgram(); - - GPU_disable_program_point_size(); - glDisable(GL_BLEND); + node_draw_sockets(&ar->v2d, C, ntree, node, false, node->flag & SELECT); UI_block_end(C, node->block); UI_block_draw(C, node->block); diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index 7e1a6216608..c532846d1c4 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -620,39 +620,16 @@ static void node_draw_mute_line(View2D *v2d, SpaceNode *snode, bNode *node) glDisable(GL_LINE_SMOOTH); } -/* this might have some more generic use */ -static void node_circle_draw(float x, float y, float size, const float col[4], int highlight, unsigned pos) +static void node_socket_circle_draw(const bContext *C, bNodeTree *ntree, PointerRNA node_ptr, bNodeSocket *sock, unsigned pos, unsigned col) { - /* set handle size */ - immUniform1f("size", 2.0f * size); //2 * size to have diameter - - if (highlight) { - float c[3]; - UI_GetThemeColor3fv(TH_TEXT_HI, c); - immUniform4f("outlineColor", c[0], c[1], c[2], 1.0f); - immUniform1f("outlineWidth", 1.5f); - } - else { - immUniform4f("outlineColor", 0, 0, 0, 0.6); - immUniform1f("outlineWidth", 1.0f); - } - - immUniformColor4fv(col); - - immBegin(GL_POINTS, 1); - immVertex2f(pos , x, y); - immEnd(); -} - -void node_socket_circle_draw(const bContext *C, bNodeTree *ntree, bNode *node, bNodeSocket *sock, float size, int highlight, unsigned pos) -{ - 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); - node_circle_draw(sock->locx, sock->locy, size, color, highlight, pos); + + immAttrib4fv(col, color); + immVertex2f(pos, sock->locx, sock->locy); } /* ************** Socket callbacks *********** */ @@ -763,10 +740,115 @@ void node_draw_shadow(SpaceNode *snode, bNode *node, float radius, float alpha) } } +void node_draw_sockets(View2D *v2d, const bContext *C, bNodeTree *ntree, bNode *node, bool draw_outputs, bool select_all) +{ + PointerRNA node_ptr; + RNA_pointer_create((ID *)ntree, &RNA_Node, node, &node_ptr); + + float xscale, yscale; + UI_view2d_scale_get(v2d, &xscale, &yscale); + + VertexFormat *format = immVertexFormat(); + unsigned pos = add_attrib(format, "pos", GL_FLOAT, 2, KEEP_FLOAT); + unsigned col = add_attrib(format, "color", GL_FLOAT, 4, KEEP_FLOAT); + + glEnable(GL_BLEND); + GPU_enable_program_point_size(); + + immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_VARYING_COLOR_OUTLINE_SMOOTH); + + /* set handle size */ + immUniform1f("size", 2.0f * NODE_SOCKSIZE * xscale); // 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(GL_POINTS, BLI_listbase_count(&node->inputs) + BLI_listbase_count(&node->outputs)); + } + + /* 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(GL_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 */ @@ -775,16 +857,13 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN float color[4]; char showname[128]; /* 128 used below */ View2D *v2d = &ar->v2d; - float xscale, yscale; - - UI_view2d_scale_get(v2d, &xscale, &yscale); /* 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; @@ -871,12 +950,8 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN UI_draw_icon_tri(rct->xmin + 0.5f * U.widget_unit, rct->ymax - NODE_DY / 2.0f, 'v'); } - /* 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); +#if 0 /* this isn't doing anything for the label, so commenting out */ + UI_ThemeColor((node->flag & SELECT) ? TH_TEXT_HI : TH_TEXT); #endif nodeLabel(ntree, node, showname, sizeof(showname)); @@ -903,14 +978,10 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN /* outline active and selected emphasis */ if (node->flag & SELECT) { - glEnable(GL_BLEND); glEnable(GL_LINE_SMOOTH); - - if (node->flag & NODE_ACTIVE) - UI_GetThemeColorShadeAlpha4fv(TH_ACTIVE, 0, -40, color); - else - UI_GetThemeColorShadeAlpha4fv(TH_SELECT, 0, -40, color); + + 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, color); @@ -923,33 +994,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN if (node->flag & NODE_MUTED) node_draw_mute_line(v2d, snode, node); - unsigned pos = add_attrib(immVertexFormat(), "pos", GL_FLOAT, 2, KEEP_FLOAT); - - glEnable(GL_BLEND); - GPU_enable_program_point_size(); - - immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_SMOOTH); - - /* socket inputs, buttons */ - for (sock = node->inputs.first; sock; sock = sock->next) { - if (nodeSocketIsHidden(sock)) - continue; - - node_socket_circle_draw(C, ntree, node, sock, NODE_SOCKSIZE * xscale, sock->flag & SELECT, pos); - } - - /* socket outputs */ - for (sock = node->outputs.first; sock; sock = sock->next) { - if (nodeSocketIsHidden(sock)) - continue; - - node_socket_circle_draw(C, ntree, node, sock, NODE_SOCKSIZE * xscale, sock->flag & SELECT, pos); - } - - immUnbindProgram(); - - GPU_disable_program_point_size(); - glDisable(GL_BLEND); + node_draw_sockets(v2d, C, ntree, node, true, false); /* preview */ if (node->flag & NODE_PREVIEW && previews) { @@ -970,7 +1015,6 @@ 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; @@ -1007,10 +1051,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b glEnable(GL_BLEND); glEnable(GL_LINE_SMOOTH); - if (node->flag & NODE_ACTIVE) - UI_GetThemeColorShadeAlpha4fv(TH_ACTIVE, 0, -40, color); - else - UI_GetThemeColorShadeAlpha4fv(TH_SELECT, 0,-40, color); + UI_GetThemeColorShadeAlpha4fv((node->flag & NODE_ACTIVE) ? TH_ACTIVE : TH_SELECT, 0, -40, color); UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rct->xmin, rct->ymin, rct->xmax, rct->ymax, hiddenrad, color); @@ -1054,12 +1095,9 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b /* 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); - + + UI_ThemeColor((node->flag & SELECT) ? TH_SELECT : TH_TEXT); + if (node->miniwidth > 0.0f) { nodeLabel(ntree, node, showname, sizeof(showname)); @@ -1083,30 +1121,8 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b 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); - unsigned pos = add_attrib(immVertexFormat(), "pos", GL_FLOAT, 2, KEEP_FLOAT); + node_draw_sockets(v2d, C, ntree, node, true, false); - glEnable(GL_BLEND); - GPU_enable_program_point_size(); - - immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_SMOOTH); - - /* socket inputs, buttons */ - for (sock = node->inputs.first; sock; sock = sock->next) { - if (!nodeSocketIsHidden(sock)) - node_socket_circle_draw(C, ntree, node, sock, NODE_SOCKSIZE * xscale, sock->flag & SELECT, pos); - } - - /* socket outputs */ - for (sock = node->outputs.first; sock; sock = sock->next) { - if (!nodeSocketIsHidden(sock)) - node_socket_circle_draw(C, ntree, node, sock, NODE_SOCKSIZE * xscale, sock->flag & SELECT, pos); - } - - immUnbindProgram(); - - GPU_disable_program_point_size(); - glDisable(GL_BLEND); - UI_block_end(C, node->block); UI_block_draw(C, node->block); node->block = NULL; diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index 6a541c40363..3b5d32a432a 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -67,12 +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_circle_draw(const struct bContext *C, struct bNodeTree *ntree, struct bNode *node, - struct bNodeSocket *sock, float size, int highlight, unsigned pos); 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); |