Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/space_node/drawnode.c
| Context not available. | |||||
| #include "BIF_glutil.h" | #include "BIF_glutil.h" | ||||
| #include "GPU_draw.h" | #include "GPU_draw.h" | ||||
| #include "GPU_basic_shader.h" | |||||
| #include "GPU_immediate.h" | #include "GPU_immediate.h" | ||||
| #include "RNA_access.h" | #include "RNA_access.h" | ||||
| Context not available. | |||||
| BKE_image_release_ibuf(ima, ibuf, lock); | BKE_image_release_ibuf(ima, ibuf, lock); | ||||
| } | } | ||||
| /* if v2d not NULL, it clips and returns 0 if not visible */ | /* 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) | static bool node_link_bezier_points_glsl(View2D *v2d, SpaceNode *snode, bNodeLink *link, float vec[4][2]) | ||||
| { | { | ||||
| float dist, vec[4][2]; | float dist; | ||||
| float deltax, deltay; | float deltax, deltay; | ||||
| float cursor[2] = {0.0f, 0.0f}; | float cursor[2] = {0.0f, 0.0f}; | ||||
| int toreroute, fromreroute; | int toreroute, fromreroute; | ||||
| Context not available. | |||||
| } | } | ||||
| else { | else { | ||||
| /* always do all three, to prevent data hanging around */ | /* 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); | |||||
| BKE_curve_forward_diff_bezier(vec[0][1], vec[1][1], vec[2][1], vec[3][1], | |||||
| coord_array[0] + 1, resol, sizeof(float) * 2); | |||||
| return 1; | return 1; | ||||
| } | } | ||||
| return 0; | return 0; | ||||
merwin: Return true or false. | |||||
| } | } | ||||
| #define LINK_RESOL 24 | void node_draw_link_bezier_glsl(View2D *v2d, SpaceNode *snode, bNodeLink *link, | ||||
| #define LINK_ARROW 12 /* position of arrow on the link, LINK_RESOL/2 */ | int th_col1, bool do_shaded, int th_col2, bool do_triple, int th_col3, unsigned attrib_array[3]) | ||||
| #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]; | float coord_array[4][2]; | ||||
| bool drawarrow; | |||||
| float xscale, yscale; | |||||
| if (node_link_bezier_points(v2d, snode, link, coord_array, LINK_RESOL)) { | if (node_link_bezier_points_glsl(v2d, snode, link, coord_array)) { | ||||
| float dist, spline_step = 0.0f; | |||||
| int i; | |||||
| int drawarrow; | |||||
| /* store current linewidth */ | |||||
| float linew; | |||||
| float arrow[2], arrow1[2], arrow2[2]; | |||||
| const float px_fac = UI_DPI_WINDOW_FAC; | |||||
| glGetFloatv(GL_LINE_WIDTH, &linew); | |||||
| /* we can reuse the dist variable here to increment the GL curve eval amount*/ | unsigned pos = attrib_array[0]; | ||||
| dist = 1.0f / (float)LINK_RESOL; | unsigned color = attrib_array[1]; | ||||
| unsigned handle = attrib_array[2]; | |||||
| glEnable(GL_LINE_SMOOTH); | UI_view2d_scale_get(v2d, &xscale, &yscale); | ||||
| immUniform1f("scale", xscale); | |||||
| if (!do_triple) { | |||||
| immUniform1f("line_width", 3.f * UI_DPI_WINDOW_FAC); | |||||
| immUniform1f("triple_width", 0.0f); | |||||
| } | |||||
| else { | |||||
| float col[4]; | |||||
| immUniform1f("line_width", 1.5f * UI_DPI_WINDOW_FAC); | |||||
| UI_GetThemeColorShadeAlpha4fv(th_col3, -80, -120, col); | |||||
| immUniform4fv("triple_color", col); | |||||
| immUniform1f("triple_width", 5.0f * UI_DPI_WINDOW_FAC); | |||||
| } | |||||
| drawarrow = ((link->tonode && (link->tonode->type == NODE_REROUTE)) && | drawarrow = ((link->tonode && (link->tonode->type == NODE_REROUTE)) && | ||||
| (link->fromnode && (link->fromnode->type == NODE_REROUTE))); | (link->fromnode && (link->fromnode->type == NODE_REROUTE))); | ||||
| if (drawarrow) { | if (drawarrow) | ||||
| /* draw arrow in line segment LINK_ARROW */ | immUniform1i("drawarrow", 1); | ||||
| float d_xy[2], len; | else | ||||
| immUniform1i("drawarrow", 0); | |||||
merwinUnsubmitted Not Done Inline ActionsI recently added Batch_Uniform1b for booleans. Will add same thing for immediate mode so you can say this: immUniform1b("drawarrow", drawarrow); merwin: I recently added Batch_Uniform1b for booleans. Will add same thing for immediate mode so you… | |||||
| sub_v2_v2v2(d_xy, coord_array[LINK_ARROW], coord_array[LINK_ARROW - 1]); | immBegin(GL_LINES, 2); | ||||
| len = len_v2(d_xy); | float col[3]; | ||||
| mul_v2_fl(d_xy, ARROW_SIZE / len); | |||||
| arrow1[0] = coord_array[LINK_ARROW][0] - d_xy[0] + d_xy[1]; | UI_GetThemeColor3fv(th_col1, col); | ||||
| 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]; | immAttrib2fv(handle, coord_array[1]); | ||||
| arrow2[1] = coord_array[LINK_ARROW][1] - d_xy[1] + d_xy[0]; | immAttrib3fv(color, col); | ||||
| arrow[0] = coord_array[LINK_ARROW][0]; | immVertex2fv(pos, coord_array[0]); | ||||
| arrow[1] = coord_array[LINK_ARROW][1]; | |||||
| } | if (do_shaded) | ||||
| if (do_triple) { | UI_GetThemeColor3fv(th_col2, col); | ||||
| UI_ThemeColorShadeAlpha(th_col3, -80, -120); | |||||
| glLineWidth(4.0f * px_fac); | immAttrib2fv(handle, coord_array[2]); | ||||
| immAttrib3fv(color, col); | |||||
| immVertex2fv(pos, coord_array[3]); | |||||
| immEnd(); | |||||
| 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(); | |||||
| } | } | ||||
| } | } | ||||
| /* XXX using GL_LINES for shaded node lines is a workaround | /* if v2d not NULL, it clips and returns 0 if not visible */ | ||||
| * for Intel hardware, this breaks with GL_LINE_STRIP and | bool node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, float coord_array[][2], int resol) | ||||
| * changing color in begin/end blocks. | { | ||||
| */ | float dist, vec[4][2]; | ||||
| glLineWidth(1.5f * px_fac); | float deltax, deltay; | ||||
| if (do_shaded) { | float cursor[2] = {0.0f, 0.0f}; | ||||
| glBegin(GL_LINES); | int toreroute, fromreroute; | ||||
| 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); | /* this function can be called with snode null (via cut_links_intersect) */ | ||||
| glVertex2fv(coord_array[i + 1]); | /* XXX map snode->cursor back to view space */ | ||||
| if (snode) { | |||||
| cursor[0] = snode->cursor[0] * UI_DPI_FAC; | |||||
| cursor[1] = snode->cursor[1] * UI_DPI_FAC; | |||||
| } | |||||
| spline_step += dist; | /* in v0 and v3 we put begin/end points */ | ||||
| if (link->fromsock) { | |||||
| vec[0][0] = link->fromsock->locx; | |||||
| vec[0][1] = link->fromsock->locy; | |||||
| fromreroute = (link->fromnode && link->fromnode->type == NODE_REROUTE); | |||||
| } | } | ||||
| glEnd(); | else { | ||||
| if (snode == NULL) return 0; | |||||
| copy_v2_v2(vec[0], cursor); | |||||
| fromreroute = 0; | |||||
| } | |||||
| if (link->tosock) { | |||||
| vec[3][0] = link->tosock->locx; | |||||
| vec[3][1] = link->tosock->locy; | |||||
| toreroute = (link->tonode && link->tonode->type == NODE_REROUTE); | |||||
| } | } | ||||
| else { | else { | ||||
| UI_ThemeColor(th_col1); | if (snode == NULL) return 0; | ||||
| glBegin(GL_LINE_STRIP); | copy_v2_v2(vec[3], cursor); | ||||
| for (i = 0; i <= LINK_RESOL; i++) { | toreroute = 0; | ||||
| glVertex2fv(coord_array[i]); | |||||
| } | } | ||||
| glEnd(); | |||||
| /* may be called outside of drawing (so pass spacetype) */ | |||||
| dist = UI_GetThemeValueType(TH_NODE_CURVING, SPACE_NODE) * 0.10f * fabsf(vec[0][0] - vec[3][0]); | |||||
| deltax = vec[3][0] - vec[0][0]; | |||||
| deltay = vec[3][1] - vec[0][1]; | |||||
| /* check direction later, for top sockets */ | |||||
| if (fromreroute) { | |||||
| if (ABS(deltax) > ABS(deltay)) { | |||||
| vec[1][1] = vec[0][1]; | |||||
| vec[1][0] = vec[0][0] + (deltax > 0 ? dist : -dist); | |||||
| } | |||||
| else { | |||||
| vec[1][0] = vec[0][0]; | |||||
| vec[1][1] = vec[0][1] + (deltay > 0 ? dist : -dist); | |||||
| } | |||||
| } | |||||
| else { | |||||
| vec[1][0] = vec[0][0] + dist; | |||||
| vec[1][1] = vec[0][1]; | |||||
| } | |||||
| if (toreroute) { | |||||
| if (ABS(deltax) > ABS(deltay)) { | |||||
| vec[2][1] = vec[3][1]; | |||||
| vec[2][0] = vec[3][0] + (deltax > 0 ? -dist : dist); | |||||
| } | |||||
| else { | |||||
| vec[2][0] = vec[3][0]; | |||||
| vec[2][1] = vec[3][1] + (deltay > 0 ? -dist : dist); | |||||
| } | } | ||||
| if (drawarrow) { | |||||
| glBegin(GL_LINE_STRIP); | |||||
| glVertex2fv(arrow1); | |||||
| glVertex2fv(arrow); | |||||
| glVertex2fv(arrow2); | |||||
| glEnd(); | |||||
| } | } | ||||
| else { | |||||
| 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 */ | |||||
| } | |||||
| else if (v2d && max_ffff(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) < v2d->cur.xmin) { | |||||
| /* clipped */ | |||||
| } | |||||
| else { | |||||
| /* 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); | |||||
| BKE_curve_forward_diff_bezier(vec[0][1], vec[1][1], vec[2][1], vec[3][1], | |||||
| coord_array[0] + 1, resol, sizeof(float) * 2); | |||||
| glDisable(GL_LINE_SMOOTH); | return 1; | ||||
| } | } | ||||
| return 0; | |||||
merwinUnsubmitted Not Done Inline ActionsSame here, return true or false. merwin: Same here, return true or false. | |||||
| } | } | ||||
| #if 0 /* not used in 2.5x yet */ | #if 0 /* not used in 2.5x yet */ | ||||
| Context not available. | |||||
| #endif | #endif | ||||
| /* note; this is used for fake links in groups too */ | /* note; this is used for fake links in groups too */ | ||||
| void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link) | void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link, unsigned attrib_array[3]) | ||||
| { | { | ||||
| bool do_shaded = false; | bool do_shaded = false; | ||||
| bool do_triple = false; | bool do_triple = false; | ||||
| Context not available. | |||||
| } | } | ||||
| } | } | ||||
| node_draw_link_bezier(v2d, snode, link, th_col1, do_shaded, th_col2, do_triple, th_col3); | node_draw_link_bezier_glsl(v2d, snode, link, th_col1, do_shaded, th_col2, do_triple, th_col3, attrib_array); | ||||
| // 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) | ||||
| Context not available. | |||||
Return true or false.