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
This commit is contained in:
parent
2df27995f9
commit
9632ca0a13
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue