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_graph')
-rw-r--r--source/blender/editors/space_graph/CMakeLists.txt3
-rw-r--r--source/blender/editors/space_graph/graph_buttons.c313
-rw-r--r--source/blender/editors/space_graph/graph_draw.c646
-rw-r--r--source/blender/editors/space_graph/graph_edit.c12
-rw-r--r--source/blender/editors/space_graph/graph_ops.c3
-rw-r--r--source/blender/editors/space_graph/graph_utils.c45
-rw-r--r--source/blender/editors/space_graph/space_graph.c214
7 files changed, 806 insertions, 430 deletions
diff --git a/source/blender/editors/space_graph/CMakeLists.txt b/source/blender/editors/space_graph/CMakeLists.txt
index 40a196fa95b..2840324e65e 100644
--- a/source/blender/editors/space_graph/CMakeLists.txt
+++ b/source/blender/editors/space_graph/CMakeLists.txt
@@ -23,6 +23,7 @@ set(INC
../../blenkernel
../../blenlib
../../blentranslation
+ ../../depsgraph
../../gpu
../../makesdna
../../makesrna
@@ -48,7 +49,7 @@ set(SRC
)
if(WITH_AUDASPACE)
- add_definitions(${AUDASPACE_DEFINITIONS})
+ add_definitions(-DWITH_AUDASPACE)
list(APPEND INC_SYS
${AUDASPACE_C_INCLUDE_DIRS}
diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c
index cac379f3786..2a0d5baa5c3 100644
--- a/source/blender/editors/space_graph/graph_buttons.c
+++ b/source/blender/editors/space_graph/graph_buttons.c
@@ -48,13 +48,13 @@
#include "BKE_context.h"
#include "BKE_curve.h"
-#include "BKE_depsgraph.h"
#include "BKE_fcurve.h"
#include "BKE_main.h"
#include "BKE_global.h"
#include "BKE_screen.h"
#include "BKE_unit.h"
+#include "DEG_depsgraph_build.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -154,17 +154,12 @@ static void graph_panel_properties(const bContext *C, Panel *pa)
PointerRNA fcu_ptr;
uiLayout *layout = pa->layout;
uiLayout *col, *row, *sub;
- // uiBlock *block; // UNUSED
char name[256];
int icon = 0;
if (!graph_panel_context(C, &ale, &fcu))
return;
- // UNUSED
- // block = uiLayoutGetBlock(layout);
- // UI_block_func_handle_set(block, do_graph_region_buttons, NULL);
-
/* F-Curve pointer */
RNA_pointer_create(ale->id, &RNA_FCurve, fcu, &fcu_ptr);
@@ -472,7 +467,7 @@ static void graph_panel_key_properties(const bContext *C, Panel *pa)
#define B_IPO_DEPCHANGE 10
-static void do_graph_region_driver_buttons(bContext *C, void *UNUSED(arg), int event)
+static void do_graph_region_driver_buttons(bContext *C, void *fcu_v, int event)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
@@ -480,8 +475,18 @@ static void do_graph_region_driver_buttons(bContext *C, void *UNUSED(arg), int e
switch (event) {
case B_IPO_DEPCHANGE:
{
+ /* force F-Curve & Driver to get re-evaluated (same as the old Update Dependencies) */
+ FCurve *fcu = (FCurve *)fcu_v;
+ ChannelDriver *driver = (fcu) ? fcu->driver : NULL;
+
+ /* clear invalid flags */
+ if (fcu) {
+ fcu->flag &= ~FCURVE_DISABLED;
+ driver->flag &= ~DRIVER_FLAG_INVALID;
+ }
+
/* rebuild depsgraph for the new deps */
- DAG_relations_tag_update(bmain);
+ DEG_relations_tag_update(bmain);
break;
}
}
@@ -490,23 +495,6 @@ static void do_graph_region_driver_buttons(bContext *C, void *UNUSED(arg), int e
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); // XXX could use better notifier
}
-/* callback to remove the active driver */
-static void driver_remove_cb(bContext *C, void *ale_v, void *UNUSED(arg))
-{
- bAnimListElem *ale = (bAnimListElem *)ale_v;
- ID *id = ale->id;
- FCurve *fcu = ale->data;
- ReportList *reports = CTX_wm_reports(C);
-
- /* try to get F-Curve that driver lives on, and ID block which has this AnimData */
- if (ELEM(NULL, id, fcu))
- return;
-
- /* call API method to remove this driver */
- ANIM_remove_driver(reports, id, fcu->rna_path, fcu->array_index, 0);
- ED_undo_push(C, "Remove Driver");
-}
-
/* callback to add a target variable to the active driver */
static void driver_add_var_cb(bContext *C, void *driver_v, void *UNUSED(arg))
{
@@ -728,60 +716,91 @@ static void graph_panel_driverVar__transChan(uiLayout *layout, ID *id, DriverVar
uiItemR(sub, &dtar_ptr, "transform_space", 0, IFACE_("Space"), ICON_NONE);
}
-/* driver settings for active F-Curve (only for 'Drivers' mode) */
-static void graph_panel_drivers(const bContext *C, Panel *pa)
+/* ----------------------------------------------------------------- */
+
+
+/* property driven by the driver - duplicates Active FCurve, but useful for clarity */
+static void graph_draw_driven_property_panel(uiLayout *layout, ID *id, FCurve *fcu)
{
- bAnimListElem *ale;
- FCurve *fcu;
- ChannelDriver *driver;
+ PointerRNA fcu_ptr;
+ uiLayout *row;
+ char name[256];
+ int icon = 0;
+
+ /* F-Curve pointer */
+ RNA_pointer_create(id, &RNA_FCurve, fcu, &fcu_ptr);
+
+ /* get user-friendly 'name' for F-Curve */
+ icon = getname_anim_fcurve(name, id, fcu);
+
+ /* panel layout... */
+ row = uiLayoutRow(layout, true);
+ uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_LEFT);
+
+ /* -> user friendly 'name' for datablock that owns F-Curve */
+ /* XXX: Actually, we may need the datablock icons only... (e.g. right now will show bone for bone props) */
+ uiItemL(row, id->name + 2, icon);
+
+ /* -> user friendly 'name' for F-Curve/driver target */
+ uiItemL(row, "", VICO_SMALL_TRI_RIGHT_VEC);
+ uiItemL(row, name, ICON_RNA);
+}
+
+/* UI properties panel layout for driver settings - shared for Drivers Editor and for */
+static void graph_draw_driver_settings_panel(uiLayout *layout, ID *id, FCurve *fcu, const bool is_popover)
+{
+ ChannelDriver *driver = fcu->driver;
DriverVar *dvar;
PointerRNA driver_ptr;
- uiLayout *col;
+ uiLayout *col, *row;
uiBlock *block;
uiBut *but;
- /* Get settings from context */
- if (!graph_panel_context(C, &ale, &fcu))
- return;
- driver = fcu->driver;
-
/* set event handler for panel */
- block = uiLayoutGetBlock(pa->layout); // xxx?
+ block = uiLayoutGetBlock(layout);
UI_block_func_handle_set(block, do_graph_region_driver_buttons, NULL);
- /* general actions - management */
- col = uiLayoutColumn(pa->layout, false);
- block = uiLayoutGetBlock(col);
- but = uiDefIconTextBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_FILE_REFRESH, IFACE_("Update Dependencies"),
- 0, 0, 10 * UI_UNIT_X, UI_UNIT_Y,
- NULL, 0.0, 0.0, 0, 0,
- TIP_("Force updates of dependencies"));
- UI_but_func_set(but, driver_update_flags_cb, fcu, NULL);
-
- but = uiDefIconTextBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_ZOOMOUT, IFACE_("Remove Driver"),
- 0, 0, 10 * UI_UNIT_X, UI_UNIT_Y,
- NULL, 0.0, 0.0, 0, 0,
- TIP_("Remove this driver"));
- UI_but_funcN_set(but, driver_remove_cb, MEM_dupallocN(ale), NULL);
-
/* driver-level settings - type, expressions, and errors */
- RNA_pointer_create(ale->id, &RNA_Driver, driver, &driver_ptr);
+ RNA_pointer_create(id, &RNA_Driver, driver, &driver_ptr);
- col = uiLayoutColumn(pa->layout, true);
+ col = uiLayoutColumn(layout, true);
block = uiLayoutGetBlock(col);
uiItemR(col, &driver_ptr, "type", 0, NULL, ICON_NONE);
+ {
+ char valBuf[32];
+
+ /* value of driver */
+ row = uiLayoutRow(col, true);
+ uiItemL(row, IFACE_("Driver Value:"), ICON_NONE);
+ BLI_snprintf(valBuf, sizeof(valBuf), "%.3f", driver->curval);
+ uiItemL(row, valBuf, ICON_NONE);
+ }
+
+ uiItemS(layout);
+ uiItemS(layout);
+
/* show expression box if doing scripted drivers, and/or error messages when invalid drivers exist */
if (driver->type == DRIVER_TYPE_PYTHON) {
bool bpy_data_expr_error = (strstr(driver->expression, "bpy.data.") != NULL);
bool bpy_ctx_expr_error = (strstr(driver->expression, "bpy.context.") != NULL);
/* expression */
- uiItemR(col, &driver_ptr, "expression", 0, IFACE_("Expr"), ICON_NONE);
+ /* TODO: "Show syntax hints" button */
+ col = uiLayoutColumn(layout, true);
+ block = uiLayoutGetBlock(col);
+
+ uiItemL(col, IFACE_("Expression:"), ICON_NONE);
+ uiItemR(col, &driver_ptr, "expression", 0, "", ICON_NONE);
+ uiItemR(col, &driver_ptr, "use_self", 0, NULL, ICON_NONE);
/* errors? */
+ col = uiLayoutColumn(layout, true);
+ block = uiLayoutGetBlock(col);
+
if ((G.f & G_SCRIPT_AUTOEXEC) == 0) {
+ /* TODO: Add button to enable? */
uiItemL(col, IFACE_("WARNING: Python expressions limited for security"), ICON_ERROR);
}
else if (driver->flag & DRIVER_FLAG_INVALID) {
@@ -803,6 +822,9 @@ static void graph_panel_drivers(const bContext *C, Panel *pa)
}
else {
/* errors? */
+ col = uiLayoutColumn(layout, true);
+ block = uiLayoutGetBlock(col);
+
if (driver->flag & DRIVER_FLAG_INVALID)
uiItemL(col, IFACE_("ERROR: Invalid target channel(s)"), ICON_ERROR);
@@ -822,37 +844,31 @@ static void graph_panel_drivers(const bContext *C, Panel *pa)
}
}
- col = uiLayoutColumn(pa->layout, true);
-
- if (driver->type == DRIVER_TYPE_PYTHON) {
- uiItemR(col, &driver_ptr, "use_self", 0, NULL, ICON_NONE);
- }
-
- /* debug setting */
- uiItemR(col, &driver_ptr, "show_debug_info", 0, NULL, ICON_NONE);
-
- /* value of driver */
- if (driver->flag & DRIVER_FLAG_SHOWDEBUG) {
- uiLayout *row = uiLayoutRow(col, true);
- char valBuf[32];
-
- uiItemL(row, IFACE_("Driver Value:"), ICON_NONE);
-
- BLI_snprintf(valBuf, sizeof(valBuf), "%.3f", driver->curval);
- uiItemL(row, valBuf, ICON_NONE);
- }
+ uiItemS(layout);
/* add/copy/paste driver variables */
- {
- uiLayout *row;
+ if (is_popover) {
+ /* add driver variable - add blank */
+ row = uiLayoutRow(layout, true);
+ block = uiLayoutGetBlock(row);
+ but = uiDefIconTextBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_ZOOMIN, IFACE_("Add Input Variable"),
+ 0, 0, 10 * UI_UNIT_X, UI_UNIT_Y,
+ NULL, 0.0, 0.0, 0, 0,
+ TIP_("Add a Driver Variable to keep track an input used by the driver"));
+ UI_but_func_set(but, driver_add_var_cb, driver, NULL);
+ /* add driver variable - add using eyedropper */
+ /* XXX: will this operator work like this? */
+ uiItemO(row, "", ICON_EYEDROPPER, "UI_OT_eyedropper_driver");
+ }
+ else {
/* add driver variable */
- row = uiLayoutRow(pa->layout, false);
+ row = uiLayoutRow(layout, false);
block = uiLayoutGetBlock(row);
- but = uiDefIconTextBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_ZOOMIN, IFACE_("Add Variable"),
- 0, 0, 10 * UI_UNIT_X, UI_UNIT_Y,
- NULL, 0.0, 0.0, 0, 0,
- TIP_("Driver variables ensure that all dependencies will be accounted for and that drivers will update correctly"));
+ but = uiDefIconTextBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_ZOOMIN, IFACE_("Add Input Variable"),
+ 0, 0, 10 * UI_UNIT_X, UI_UNIT_Y,
+ NULL, 0.0, 0.0, 0, 0,
+ TIP_("Driver variables ensure that all dependencies will be accounted for, eusuring that drivers will update correctly"));
UI_but_func_set(but, driver_add_var_cb, driver, NULL);
/* copy/paste (as sub-row) */
@@ -866,15 +882,15 @@ static void graph_panel_drivers(const bContext *C, Panel *pa)
/* loop over targets, drawing them */
for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
PointerRNA dvar_ptr;
- uiLayout *box, *row;
+ uiLayout *box;
uiLayout *subrow, *sub;
/* sub-layout column for this variable's settings */
- col = uiLayoutColumn(pa->layout, true);
+ col = uiLayoutColumn(layout, true);
/* 1) header panel */
box = uiLayoutBox(col);
- RNA_pointer_create(ale->id, &RNA_DriverVariable, dvar, &dvar_ptr);
+ RNA_pointer_create(id, &RNA_DriverVariable, dvar, &dvar_ptr);
row = uiLayoutRow(box, false);
block = uiLayoutGetBlock(row);
@@ -915,21 +931,21 @@ static void graph_panel_drivers(const bContext *C, Panel *pa)
/* controls to draw depends on the type of variable */
switch (dvar->type) {
case DVAR_TYPE_SINGLE_PROP: /* single property */
- graph_panel_driverVar__singleProp(box, ale->id, dvar);
+ graph_panel_driverVar__singleProp(box, id, dvar);
break;
case DVAR_TYPE_ROT_DIFF: /* rotational difference */
- graph_panel_driverVar__rotDiff(box, ale->id, dvar);
+ graph_panel_driverVar__rotDiff(box, id, dvar);
break;
case DVAR_TYPE_LOC_DIFF: /* location difference */
- graph_panel_driverVar__locDiff(box, ale->id, dvar);
+ graph_panel_driverVar__locDiff(box, id, dvar);
break;
case DVAR_TYPE_TRANSFORM_CHAN: /* transform channel */
- graph_panel_driverVar__transChan(box, ale->id, dvar);
+ graph_panel_driverVar__transChan(box, id, dvar);
break;
}
/* 3) value of variable */
- if (driver->flag & DRIVER_FLAG_SHOWDEBUG) {
+ {
char valBuf[32];
box = uiLayoutBox(col);
@@ -951,10 +967,108 @@ static void graph_panel_drivers(const bContext *C, Panel *pa)
}
}
+ uiItemS(layout);
+ uiItemS(layout);
+
+ /* XXX: This should become redundant. But sometimes the flushing fails, so keep this around for a while longer as a "last resort" */
+ row = uiLayoutRow(layout, true);
+ block = uiLayoutGetBlock(row);
+ but = uiDefIconTextBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_FILE_REFRESH, IFACE_("Update Dependencies"),
+ 0, 0, 10 * UI_UNIT_X, UI_UNIT_Y,
+ NULL, 0.0, 0.0, 0, 0,
+ TIP_("Force updates of dependencies - Only use this if drivers are not updating correctly"));
+ UI_but_func_set(but, driver_update_flags_cb, fcu, NULL);
+}
+
+/* ----------------------------------------------------------------- */
+
+
+/* panel to show property driven by the driver (in Drivers Editor) - duplicates Active FCurve, but useful for clarity */
+static void graph_panel_driven_property(const bContext *C, Panel *pa)
+{
+ bAnimListElem *ale;
+ FCurve *fcu;
+
+ if (!graph_panel_context(C, &ale, &fcu))
+ return;
+
+ graph_draw_driven_property_panel(pa->layout, ale->id, fcu);
+
+ MEM_freeN(ale);
+}
+
+/* driver settings for active F-Curve (only for 'Drivers' mode in Graph Editor, i.e. the full "Drivers Editor") */
+static void graph_panel_drivers(const bContext *C, Panel *pa)
+{
+ bAnimListElem *ale;
+ FCurve *fcu;
+
+ /* Get settings from context */
+ if (!graph_panel_context(C, &ale, &fcu))
+ return;
+
+ graph_draw_driver_settings_panel(pa->layout, ale->id, fcu, false);
+
/* cleanup */
MEM_freeN(ale);
}
+/* ----------------------------------------------------------------- */
+
+/* poll to make this not show up in the graph editor, as this is only to be used as a popup elsewhere */
+static int graph_panel_drivers_popover_poll(const bContext *C, PanelType *UNUSED(pt))
+{
+ return ED_operator_graphedit_active((bContext *)C) == false;
+}
+
+/* popover panel for driver editing anywhere in ui */
+static void graph_panel_drivers_popover(const bContext *C, Panel *pa)
+{
+ uiLayout *layout = pa->layout;
+
+ PointerRNA ptr = {{NULL}};
+ PropertyRNA *prop = NULL;
+ int index = -1;
+ uiBut *but = NULL;
+
+ /* Get active property to show driver properties for */
+ but = UI_context_active_but_prop_get((bContext *)C, &ptr, &prop, &index);
+ if (but) {
+ FCurve *fcu;
+ bool driven, special;
+
+ fcu = rna_get_fcurve_context_ui((bContext *)C,
+ &ptr, prop, index,
+ NULL, NULL, &driven, &special);
+
+ /* Hack: Force all buttons in this panel to be able to know the driver button
+ * this panel is getting spawned from, so that things like the "Open Drivers Editor"
+ * button will work.
+ */
+ uiLayoutSetContextFromBut(layout, but);
+
+ /* Populate Panel - With a combination of the contents of the Driven and Driver panels */
+ if (fcu) {
+ ID *id = ptr.id.data;
+
+ /* Driven Property Settings */
+ uiItemL(layout, IFACE_("Driven Property:"), ICON_NONE);
+ graph_draw_driven_property_panel(pa->layout, id, fcu);
+ /* TODO: All vs Single */
+
+ uiItemS(layout);
+ uiItemS(layout);
+
+ /* Drivers Settings */
+ uiItemL(layout, IFACE_("Driver Settings:"), ICON_NONE);
+ graph_draw_driver_settings_panel(pa->layout, id, fcu, true);
+ }
+ }
+
+ /* Show drivers editor is always visible */
+ uiItemO(layout, IFACE_("Show in Drivers Editor"), ICON_DRIVER, "SCREEN_OT_drivers_editor_show");
+}
+
/* ******************* F-Modifiers ******************************** */
/* All the drawing code is in editors/animation/fmodifier_ui.c */
@@ -1035,16 +1149,33 @@ void graph_buttons_register(ARegionType *art)
pt->poll = graph_panel_poll;
BLI_addtail(&art->paneltypes, pt);
+ pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel drivers driven");
+ strcpy(pt->idname, "GRAPH_PT_driven_property");
+ strcpy(pt->label, N_("Driven Property"));
+ strcpy(pt->category, "Drivers");
+ strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ pt->draw = graph_panel_driven_property;
+ pt->poll = graph_panel_drivers_poll;
+ BLI_addtail(&art->paneltypes, pt);
pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel drivers");
strcpy(pt->idname, "GRAPH_PT_drivers");
- strcpy(pt->label, N_("Drivers"));
+ strcpy(pt->label, N_("Driver"));
strcpy(pt->category, "Drivers");
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->draw = graph_panel_drivers;
pt->poll = graph_panel_drivers_poll;
BLI_addtail(&art->paneltypes, pt);
+ pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel drivers pover");
+ strcpy(pt->idname, "GRAPH_PT_drivers_popover");
+ strcpy(pt->label, N_("Add/Edit Driver"));
+ strcpy(pt->category, "Drivers");
+ strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ pt->draw = graph_panel_drivers_popover;
+ pt->poll = graph_panel_drivers_popover_poll;
+ BLI_addtail(&art->paneltypes, pt);
+
pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel modifiers");
strcpy(pt->idname, "GRAPH_PT_modifiers");
strcpy(pt->label, N_("Modifiers"));
@@ -1076,7 +1207,7 @@ static int graph_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op))
void GRAPH_OT_properties(wmOperatorType *ot)
{
- ot->name = "Properties";
+ ot->name = "Toggle Sidebar";
ot->idname = "GRAPH_OT_properties";
ot->description = "Toggle the properties region visibility";
diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c
index 9a94bb9072b..7c6af0b4c62 100644
--- a/source/blender/editors/space_graph/graph_draw.c
+++ b/source/blender/editors/space_graph/graph_draw.c
@@ -46,10 +46,12 @@
#include "BKE_curve.h"
#include "BKE_fcurve.h"
-
-#include "BIF_gl.h"
#include "BIF_glutil.h"
+#include "GPU_draw.h"
+#include "GPU_immediate.h"
+#include "GPU_matrix.h"
+
#include "ED_anim_api.h"
#include "graph_intern.h"
@@ -83,37 +85,58 @@ static void draw_fcurve_modifier_controls_envelope(FModifier *fcm, View2D *v2d)
const float fac = 0.05f * BLI_rctf_size_x(&v2d->cur);
int i;
+ const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+
+ glLineWidth(1.0f);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
+
+ immUniform1i("num_colors", 0); /* Simple dashes. */
+ immUniformColor3f(0.0f, 0.0f, 0.0f);
+ immUniform1f("dash_width", 10.0f);
+ immUniform1f("dash_factor", 0.5f);
+
/* draw two black lines showing the standard reference levels */
- glColor3f(0.0f, 0.0f, 0.0f);
- glLineWidth(1);
- setlinestyle(5);
- glBegin(GL_LINES);
- glVertex2f(v2d->cur.xmin, env->midval + env->min);
- glVertex2f(v2d->cur.xmax, env->midval + env->min);
+ immBegin(GWN_PRIM_LINES, 4);
+ immVertex2f(shdr_pos, v2d->cur.xmin, env->midval + env->min);
+ immVertex2f(shdr_pos, v2d->cur.xmax, env->midval + env->min);
- glVertex2f(v2d->cur.xmin, env->midval + env->max);
- glVertex2f(v2d->cur.xmax, env->midval + env->max);
- glEnd();
- setlinestyle(0);
+ immVertex2f(shdr_pos, v2d->cur.xmin, env->midval + env->max);
+ immVertex2f(shdr_pos, v2d->cur.xmax, env->midval + env->max);
+ immEnd();
- /* set size of vertices (non-adjustable for now) */
- glPointSize(2.0f);
+ immUnbindProgram();
- /* for now, point color is fixed, and is white */
- glColor3f(1.0f, 1.0f, 1.0f);
+ if (env->totvert > 0) {
+ /* set size of vertices (non-adjustable for now) */
+ glPointSize(2.0f);
- glBegin(GL_POINTS);
- for (i = 0, fed = env->data; i < env->totvert; i++, fed++) {
- /* only draw if visible
- * - min/max here are fixed, not relative
- */
- if (IN_RANGE(fed->time, (v2d->cur.xmin - fac), (v2d->cur.xmax + fac))) {
- glVertex2f(fed->time, fed->min);
- glVertex2f(fed->time, fed->max);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ /* for now, point color is fixed, and is white */
+ immUniformColor3f(1.0f, 1.0f, 1.0f);
+
+ immBeginAtMost(GWN_PRIM_POINTS, env->totvert * 2);
+
+ for (i = 0, fed = env->data; i < env->totvert; i++, fed++) {
+ /* only draw if visible
+ * - min/max here are fixed, not relative
+ */
+ if (IN_RANGE(fed->time, (v2d->cur.xmin - fac), (v2d->cur.xmax + fac))) {
+ immVertex2f(shdr_pos, fed->time, fed->min);
+ immVertex2f(shdr_pos, fed->time, fed->max);
+ }
}
+
+ immEnd();
+
+ immUnbindProgram();
}
- glEnd();
}
/* *************************** */
@@ -121,16 +144,37 @@ static void draw_fcurve_modifier_controls_envelope(FModifier *fcm, View2D *v2d)
/* Points ---------------- */
-/* helper func - draw keyframe vertices only for an F-Curve */
-static void draw_fcurve_vertices_keyframes(FCurve *fcu, SpaceIpo *UNUSED(sipo), View2D *v2d, short edit, short sel)
+/* helper func - set color to draw F-Curve data with */
+static void set_fcurve_vertex_color(FCurve *fcu, bool sel)
+{
+ /* Fade the 'intensity' of the vertices based on the selection of the curves too */
+ int alphaOffset = (int)((fcurve_display_alpha(fcu) - 1.0f) * 255);
+
+ float color[4];
+
+ /* Set color of curve vertex based on state of curve (i.e. 'Edit' Mode) */
+ if ((fcu->flag & FCURVE_PROTECTED) == 0) {
+ /* Curve's points ARE BEING edited */
+ UI_GetThemeColorShadeAlpha4fv(sel ? TH_VERTEX_SELECT : TH_VERTEX, 0, alphaOffset, color);
+ }
+ else {
+ /* Curve's points CANNOT BE edited */
+ UI_GetThemeColorShadeAlpha4fv(sel ? TH_TEXT_HI : TH_TEXT, 0, alphaOffset, color);
+ }
+
+ immUniformColor4fv(color);
+}
+
+static void draw_fcurve_selected_keyframe_vertices(FCurve *fcu, View2D *v2d, bool edit, bool sel, unsigned pos)
{
- BezTriple *bezt = fcu->bezt;
const float fac = 0.05f * BLI_rctf_size_x(&v2d->cur);
- int i;
- glBegin(GL_POINTS);
+ set_fcurve_vertex_color(fcu, sel);
+
+ immBeginAtMost(GWN_PRIM_POINTS, fcu->totvert);
- for (i = 0; i < fcu->totvert; i++, bezt++) {
+ BezTriple *bezt = fcu->bezt;
+ for (int i = 0; i < fcu->totvert; i++, bezt++) {
/* as an optimization step, only draw those in view
* - we apply a correction factor to ensure that points don't pop in/out due to slight twitches of view size
*/
@@ -141,79 +185,49 @@ static void draw_fcurve_vertices_keyframes(FCurve *fcu, SpaceIpo *UNUSED(sipo),
* -
*/
if ((bezt->f2 & SELECT) == sel)
- glVertex3fv(bezt->vec[1]);
+ immVertex2fv(pos, bezt->vec[1]);
}
else {
/* no check for selection here, as curve is not editable... */
/* XXX perhaps we don't want to even draw points? maybe add an option for that later */
- glVertex3fv(bezt->vec[1]);
+ immVertex2fv(pos, bezt->vec[1]);
}
}
}
- glEnd();
+ immEnd();
}
-
-/* helper func - draw handle vertex for an F-Curve as a round unfilled circle
- * NOTE: the caller MUST HAVE GL_LINE_SMOOTH & GL_BLEND ENABLED, otherwise, the controls don't
- * have a consistent appearance (due to off-pixel alignments)...
- */
-static void draw_fcurve_handle_control(float x, float y, float xscale, float yscale, float hsize)
+/* helper func - draw keyframe vertices only for an F-Curve */
+static void draw_fcurve_keyframe_vertices(FCurve *fcu, View2D *v2d, bool edit, unsigned pos)
{
- static GLuint displist = 0;
-
- /* initialize round circle shape */
- if (displist == 0) {
- GLUquadricObj *qobj;
+ immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
- displist = glGenLists(1);
- glNewList(displist, GL_COMPILE);
+ immUniform1f("size", UI_GetThemeValuef(TH_VERTEX_SIZE) * U.pixelsize);
- qobj = gluNewQuadric();
- gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
- gluDisk(qobj, 0, 0.7, 8, 1);
- gluDeleteQuadric(qobj);
+ draw_fcurve_selected_keyframe_vertices(fcu, v2d, edit, false, pos);
+ draw_fcurve_selected_keyframe_vertices(fcu, v2d, edit, true, pos);
- glEndList();
- }
-
- /* adjust view transform before starting */
- glTranslatef(x, y, 0.0f);
- glScalef(1.0f / xscale * hsize, 1.0f / yscale * hsize, 1.0f);
-
- /* draw! */
- glCallList(displist);
-
- /* restore view transform */
- glScalef(xscale / hsize, yscale / hsize, 1.0);
- glTranslatef(-x, -y, 0.0f);
+ immUnbindProgram();
}
+
/* helper func - draw handle vertices only for an F-Curve (if it is not protected) */
-static void draw_fcurve_vertices_handles(FCurve *fcu, SpaceIpo *sipo, View2D *v2d, short sel, short sel_handle_only, float units_scale)
+static void draw_fcurve_selected_handle_vertices(FCurve *fcu, View2D *v2d, bool sel, bool sel_handle_only, unsigned pos)
{
- BezTriple *bezt = fcu->bezt;
- BezTriple *prevbezt = NULL;
- float hsize, xscale, yscale;
- int i;
-
- /* get view settings */
- hsize = UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE) * U.pixelsize;
- UI_view2d_scale_get(v2d, &xscale, &yscale);
-
- /* Compensate OGL scale sued for unit mapping, so circle will be circle, not ellipse */
- yscale *= units_scale;
+ (void) v2d; /* TODO: use this to draw only points in view */
/* set handle color */
- if (sel) UI_ThemeColor(TH_HANDLE_VERTEX_SELECT);
- else UI_ThemeColor(TH_HANDLE_VERTEX);
+ float hcolor[3];
+ UI_GetThemeColor3fv(sel ? TH_HANDLE_VERTEX_SELECT : TH_HANDLE_VERTEX, hcolor);
+ immUniform4f("outlineColor", hcolor[0], hcolor[1], hcolor[2], 1.0f);
+ immUniformColor3fvAlpha(hcolor, 0.01f); /* almost invisible - only keep for smoothness */
- /* anti-aliased lines for more consistent appearance */
- if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) glEnable(GL_LINE_SMOOTH);
- glEnable(GL_BLEND);
+ immBeginAtMost(GWN_PRIM_POINTS, fcu->totvert * 2);
- for (i = 0; i < fcu->totvert; i++, prevbezt = bezt, bezt++) {
+ BezTriple *bezt = fcu->bezt;
+ BezTriple *prevbezt = NULL;
+ for (int i = 0; i < fcu->totvert; i++, prevbezt = bezt, bezt++) {
/* Draw the editmode handles for a bezier curve (others don't have handles)
* if their selection status matches the selection status we're drawing for
* - first handle only if previous beztriple was bezier-mode
@@ -225,68 +239,61 @@ static void draw_fcurve_vertices_handles(FCurve *fcu, SpaceIpo *sipo, View2D *v2
if (!sel_handle_only || BEZT_ISSEL_ANY(bezt)) {
if ((!prevbezt && (bezt->ipo == BEZT_IPO_BEZ)) || (prevbezt && (prevbezt->ipo == BEZT_IPO_BEZ))) {
if ((bezt->f1 & SELECT) == sel) /* && v2d->cur.xmin < bezt->vec[0][0] < v2d->cur.xmax)*/
- draw_fcurve_handle_control(bezt->vec[0][0], bezt->vec[0][1], xscale, yscale, hsize);
+ immVertex2fv(pos, bezt->vec[0]);
}
if (bezt->ipo == BEZT_IPO_BEZ) {
if ((bezt->f3 & SELECT) == sel) /* && v2d->cur.xmin < bezt->vec[2][0] < v2d->cur.xmax)*/
- draw_fcurve_handle_control(bezt->vec[2][0], bezt->vec[2][1], xscale, yscale, hsize);
+ immVertex2fv(pos, bezt->vec[2]);
}
}
}
- if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) glDisable(GL_LINE_SMOOTH);
- glDisable(GL_BLEND);
+ immEnd();
}
-/* helper func - set color to draw F-Curve data with */
-static void set_fcurve_vertex_color(FCurve *fcu, short sel)
+/* helper func - draw handle vertices only for an F-Curve (if it is not protected) */
+static void draw_fcurve_handle_vertices(FCurve *fcu, View2D *v2d, bool sel_handle_only, unsigned pos)
{
- /* Fade the 'intensity' of the vertices based on the selection of the curves too */
- int alphaOffset = (int)((fcurve_display_alpha(fcu) - 1.0f) * 255);
+ /* smooth outlines for more consistent appearance */
+ immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA);
- /* Set color of curve vertex based on state of curve (i.e. 'Edit' Mode) */
- if ((fcu->flag & FCURVE_PROTECTED) == 0) {
- /* Curve's points ARE BEING edited */
- if (sel) UI_ThemeColorShadeAlpha(TH_VERTEX_SELECT, 0, alphaOffset);
- else UI_ThemeColorShadeAlpha(TH_VERTEX, 0, alphaOffset);
- }
- else {
- /* Curve's points CANNOT BE edited */
- if (sel) UI_ThemeColorShadeAlpha(TH_TEXT_HI, 0, alphaOffset);
- else UI_ThemeColorShadeAlpha(TH_TEXT, 0, alphaOffset);
- }
+ /* set handle size */
+ immUniform1f("size", (1.4f * UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE)) * U.pixelsize);
+ immUniform1f("outlineWidth", 1.5f * U.pixelsize);
+
+ draw_fcurve_selected_handle_vertices(fcu, v2d, false, sel_handle_only, pos);
+ draw_fcurve_selected_handle_vertices(fcu, v2d, true, sel_handle_only, pos);
+
+ immUnbindProgram();
}
-static void draw_fcurve_vertices(SpaceIpo *sipo, ARegion *ar, FCurve *fcu, short do_handles, short sel_handle_only, float units_scale)
+static void draw_fcurve_vertices(ARegion *ar, FCurve *fcu, bool do_handles, bool sel_handle_only)
{
View2D *v2d = &ar->v2d;
/* only draw points if curve is visible
- * - draw unselected points before selected points as separate passes to minimize color-changing overhead
- * (XXX dunno if this is faster than drawing all in one pass though)
- * and also to make sure in the case of overlapping points that the selected is always visible
+ * - draw unselected points before selected points as separate passes
+ * to make sure in the case of overlapping points that the selected is always visible
* - draw handles before keyframes, so that keyframes will overlap handles (keyframes are more important for users)
*/
- glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
+ unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+
+ glEnable(GL_BLEND);
+ GPU_enable_program_point_size();
/* draw the two handles first (if they're shown, the curve doesn't have just a single keyframe, and the curve is being edited) */
if (do_handles) {
- set_fcurve_vertex_color(fcu, 0);
- draw_fcurve_vertices_handles(fcu, sipo, v2d, 0, sel_handle_only, units_scale);
-
- set_fcurve_vertex_color(fcu, 1);
- draw_fcurve_vertices_handles(fcu, sipo, v2d, 1, sel_handle_only, units_scale);
+ draw_fcurve_handle_vertices(fcu, v2d, sel_handle_only, pos);
}
/* draw keyframes over the handles */
- set_fcurve_vertex_color(fcu, 0);
- draw_fcurve_vertices_keyframes(fcu, sipo, v2d, !(fcu->flag & FCURVE_PROTECTED), 0);
+ draw_fcurve_keyframe_vertices(fcu, v2d, !(fcu->flag & FCURVE_PROTECTED), pos);
- set_fcurve_vertex_color(fcu, 1);
- draw_fcurve_vertices_keyframes(fcu, sipo, v2d, !(fcu->flag & FCURVE_PROTECTED), 1);
+ GPU_disable_program_point_size();
+ glDisable(GL_BLEND);
}
/* Handles ---------------- */
@@ -303,10 +310,10 @@ static bool draw_fcurve_handles_check(SpaceIpo *sipo, FCurve *fcu)
(fcu->totvert <= 1) /* do not show handles if there is only 1 keyframe, otherwise they all clump together in an ugly ball */
)
{
- return 0;
+ return false;
}
else {
- return 1;
+ return true;
}
}
@@ -316,11 +323,12 @@ static void draw_fcurve_handles(SpaceIpo *sipo, FCurve *fcu)
{
int sel, b;
- /* a single call to GL_LINES here around these calls should be sufficient to still
- * get separate line segments, but which aren't wrapped with GL_LINE_STRIP every time we
- * want a single line
- */
- glBegin(GL_LINES);
+ Gwn_VertFormat *format = immVertexFormat();
+ unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
+
+ immBeginAtMost(GWN_PRIM_LINES, 4 * 2 * fcu->totvert);
/* slightly hacky, but we want to draw unselected points before selected ones
* so that selected points are clearly visible
@@ -348,18 +356,20 @@ static void draw_fcurve_handles(SpaceIpo *sipo, FCurve *fcu)
if ((!prevbezt && (bezt->ipo == BEZT_IPO_BEZ)) || (prevbezt && (prevbezt->ipo == BEZT_IPO_BEZ))) {
UI_GetThemeColor3ubv(basecol + bezt->h1, col);
col[3] = fcurve_display_alpha(fcu) * 255;
- glColor4ubv((GLubyte *)col);
-
- glVertex2fv(fp); glVertex2fv(fp + 3);
+ immAttrib4ubv(color, col);
+ immVertex2fv(pos, fp);
+ immAttrib4ubv(color, col);
+ immVertex2fv(pos, fp + 3);
}
/* only draw second handle if this segment is bezier */
if (bezt->ipo == BEZT_IPO_BEZ) {
UI_GetThemeColor3ubv(basecol + bezt->h2, col);
col[3] = fcurve_display_alpha(fcu) * 255;
- glColor4ubv((GLubyte *)col);
-
- glVertex2fv(fp + 3); glVertex2fv(fp + 6);
+ immAttrib4ubv(color, col);
+ immVertex2fv(pos, fp + 3);
+ immAttrib4ubv(color, col);
+ immVertex2fv(pos, fp + 6);
}
}
else {
@@ -370,9 +380,10 @@ static void draw_fcurve_handles(SpaceIpo *sipo, FCurve *fcu)
fp = bezt->vec[0];
UI_GetThemeColor3ubv(basecol + bezt->h1, col);
col[3] = fcurve_display_alpha(fcu) * 255;
- glColor4ubv((GLubyte *)col);
-
- glVertex2fv(fp); glVertex2fv(fp + 3);
+ immAttrib4ubv(color, col);
+ immVertex2fv(pos, fp);
+ immAttrib4ubv(color, col);
+ immVertex2fv(pos, fp + 3);
}
/* only draw second handle if this segment is bezier, and selection is ok */
@@ -382,15 +393,17 @@ static void draw_fcurve_handles(SpaceIpo *sipo, FCurve *fcu)
fp = bezt->vec[1];
UI_GetThemeColor3ubv(basecol + bezt->h2, col);
col[3] = fcurve_display_alpha(fcu) * 255;
- glColor4ubv((GLubyte *)col);
-
- glVertex2fv(fp); glVertex2fv(fp + 3);
+ immAttrib4ubv(color, col);
+ immVertex2fv(pos, fp);
+ immAttrib4ubv(color, col);
+ immVertex2fv(pos, fp + 3);
}
}
}
}
- glEnd(); /* GL_LINES */
+ immEnd();
+ immUnbindProgram();
}
/* Samples ---------------- */
@@ -399,36 +412,24 @@ static void draw_fcurve_handles(SpaceIpo *sipo, FCurve *fcu)
* NOTE: the caller MUST HAVE GL_LINE_SMOOTH & GL_BLEND ENABLED, otherwise, the controls don't
* have a consistent appearance (due to off-pixel alignments)...
*/
-static void draw_fcurve_sample_control(float x, float y, float xscale, float yscale, float hsize)
+static void draw_fcurve_sample_control(float x, float y, float xscale, float yscale, float hsize, unsigned int pos)
{
- static GLuint displist = 0;
-
- /* initialize X shape */
- if (displist == 0) {
- displist = glGenLists(1);
- glNewList(displist, GL_COMPILE);
-
- glBegin(GL_LINES);
- glVertex2f(-0.7f, -0.7f);
- glVertex2f(+0.7f, +0.7f);
-
- glVertex2f(-0.7f, +0.7f);
- glVertex2f(+0.7f, -0.7f);
- glEnd(); /* GL_LINES */
-
- glEndList();
- }
-
/* adjust view transform before starting */
- glTranslatef(x, y, 0.0f);
- glScalef(1.0f / xscale * hsize, 1.0f / yscale * hsize, 1.0f);
+ gpuPushMatrix();
+ gpuTranslate2f(x, y);
+ gpuScale2f(1.0f / xscale * hsize, 1.0f / yscale * hsize);
- /* draw! */
- glCallList(displist);
+ /* draw X shape */
+ immBegin(GWN_PRIM_LINES, 4);
+ immVertex2f(pos, -0.7f, -0.7f);
+ immVertex2f(pos, +0.7f, +0.7f);
+
+ immVertex2f(pos, -0.7f, +0.7f);
+ immVertex2f(pos, +0.7f, -0.7f);
+ immEnd();
/* restore view transform */
- glScalef(xscale / hsize, yscale / hsize, 1.0);
- glTranslatef(-x, -y, 0.0f);
+ gpuPopMatrix();
}
/* helper func - draw keyframe vertices only for an F-Curve */
@@ -441,10 +442,6 @@ static void draw_fcurve_samples(SpaceIpo *sipo, ARegion *ar, FCurve *fcu)
hsize = UI_GetThemeValuef(TH_VERTEX_SIZE);
UI_view2d_scale_get(&ar->v2d, &xscale, &yscale);
- /* set vertex color */
- if (fcu->flag & (FCURVE_ACTIVE | FCURVE_SELECTED)) UI_ThemeColor(TH_TEXT_HI);
- else UI_ThemeColor(TH_TEXT);
-
/* get verts */
first = fcu->fpt;
last = (first) ? (first + (fcu->totvert - 1)) : (NULL);
@@ -455,8 +452,15 @@ static void draw_fcurve_samples(SpaceIpo *sipo, ARegion *ar, FCurve *fcu)
if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
- draw_fcurve_sample_control(first->vec[0], first->vec[1], xscale, yscale, hsize);
- draw_fcurve_sample_control(last->vec[0], last->vec[1], xscale, yscale, hsize);
+ unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformThemeColor((fcu->flag & FCURVE_SELECTED) ? TH_TEXT_HI : TH_TEXT);
+
+ draw_fcurve_sample_control(first->vec[0], first->vec[1], xscale, yscale, hsize, pos);
+ draw_fcurve_sample_control(last->vec[0], last->vec[1], xscale, yscale, hsize, pos);
+
+ immUnbindProgram();
glDisable(GL_BLEND);
if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) glDisable(GL_LINE_SMOOTH);
@@ -466,7 +470,7 @@ static void draw_fcurve_samples(SpaceIpo *sipo, ARegion *ar, FCurve *fcu)
/* Curve ---------------- */
/* helper func - just draw the F-Curve by sampling the visible region (for drawing curves with modifiers) */
-static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d, View2DGrid *grid)
+static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d, View2DGrid *grid, unsigned int pos)
{
SpaceIpo *sipo = (SpaceIpo *)ac->sl;
ChannelDriver *driver;
@@ -536,37 +540,50 @@ static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d
* - apply the unit correction factor to the calculated values so that
* the displayed values appear correctly in the viewport
*/
- glBegin(GL_LINE_STRIP);
n = (etime - stime) / samplefreq + 0.5f;
- for (i = 0; i <= n; i++) {
- float ctime = stime + i * samplefreq;
- glVertex2f(ctime, (evaluate_fcurve(fcu, ctime) + offset) * unitFac);
- }
- glEnd();
+ if (n > 0) {
+ immBegin(GWN_PRIM_LINE_STRIP, (n + 1));
+
+ for (i = 0; i <= n; i++) {
+ float ctime = stime + i * samplefreq;
+ immVertex2f(pos, ctime, (evaluate_fcurve(fcu, ctime) + offset) * unitFac);
+ }
+
+ immEnd();
+ }
/* restore driver */
fcu->driver = driver;
}
/* helper func - draw a samples-based F-Curve */
-static void draw_fcurve_curve_samples(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d)
+static void draw_fcurve_curve_samples(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d, const uint shdr_pos)
{
FPoint *prevfpt = fcu->fpt;
FPoint *fpt = prevfpt + 1;
float fac, v[2];
- int b = fcu->totvert - 1;
+ int b = fcu->totvert;
float unit_scale, offset;
short mapping_flag = ANIM_get_normalization_flags(ac);
+ int count = fcu->totvert;
+
+ if (prevfpt->vec[0] > v2d->cur.xmin) {
+ count++;
+ }
+
+ if ((prevfpt + b - 1)->vec[0] < v2d->cur.xmax) {
+ count++;
+ }
/* apply unit mapping */
- glPushMatrix();
+ gpuPushMatrix();
unit_scale = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag, &offset);
- glScalef(1.0f, unit_scale, 1.0f);
- glTranslatef(0.0f, offset, 0.0f);
+ gpuScale2f(1.0f, unit_scale);
+ gpuTranslate2f(0.0f, offset);
- glBegin(GL_LINE_STRIP);
+ immBegin(GWN_PRIM_LINE_STRIP, count);
/* extrapolate to left? - left-side of view comes before first keyframe? */
if (prevfpt->vec[0] > v2d->cur.xmin) {
@@ -584,26 +601,19 @@ static void draw_fcurve_curve_samples(bAnimContext *ac, ID *id, FCurve *fcu, Vie
v[1] = prevfpt->vec[1] - fac * (prevfpt->vec[1] - fpt->vec[1]);
}
- glVertex2fv(v);
+ immVertex2fv(shdr_pos, v);
}
- /* if only one sample, add it now */
- if (fcu->totvert == 1)
- glVertex2fv(prevfpt->vec);
-
/* loop over samples, drawing segments */
/* draw curve between first and last keyframe (if there are enough to do so) */
while (b--) {
/* Linear interpolation: just add one point (which should add a new line segment) */
- glVertex2fv(prevfpt->vec);
+ immVertex2fv(shdr_pos, prevfpt->vec);
/* get next pointers */
- prevfpt = fpt;
- fpt++;
-
- /* last point? */
- if (b == 0)
- glVertex2fv(prevfpt->vec);
+ if (b > 0) {
+ prevfpt++;
+ }
}
/* extrapolate to right? (see code for left-extrapolation above too) */
@@ -623,11 +633,12 @@ static void draw_fcurve_curve_samples(bAnimContext *ac, ID *id, FCurve *fcu, Vie
v[1] = prevfpt->vec[1] - fac * (prevfpt->vec[1] - fpt->vec[1]);
}
- glVertex2fv(v);
+ immVertex2fv(shdr_pos, v);
}
- glEnd();
- glPopMatrix();
+ immEnd();
+
+ gpuPopMatrix();
}
/* helper func - check if the F-Curve only contains easily drawable segments
@@ -648,7 +659,7 @@ static bool fcurve_can_use_simple_bezt_drawing(FCurve *fcu)
}
/* helper func - draw one repeat of an F-Curve (using Bezier curve approximations) */
-static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d)
+static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d, unsigned int pos)
{
BezTriple *prevbezt = fcu->bezt;
BezTriple *bezt = prevbezt + 1;
@@ -661,12 +672,15 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
short mapping_flag = ANIM_get_normalization_flags(ac);
/* apply unit mapping */
- glPushMatrix();
+ gpuPushMatrix();
unit_scale = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag, &offset);
- glScalef(1.0f, unit_scale, 1.0f);
- glTranslatef(0.0f, offset, 0.0f);
+ gpuScale2f(1.0f, unit_scale);
+ gpuTranslate2f(0.0f, offset);
- glBegin(GL_LINE_STRIP);
+ /* For now, this assumes the worst case scenario, where all the keyframes have
+ * bezier interpolation, and are drawn at full res.
+ * This is tricky to optimize, but maybe can be improved at some point... */
+ immBeginAtMost(GWN_PRIM_LINE_STRIP, (b * 32 + 3));
/* extrapolate to left? */
if (prevbezt->vec[1][0] > v2d->cur.xmin) {
@@ -691,14 +705,14 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
v1[1] = prevbezt->vec[1][1] - fac * (prevbezt->vec[0][1] - prevbezt->vec[1][1]);
}
- glVertex2fv(v1);
+ immVertex2fv(pos, v1);
}
/* if only one keyframe, add it now */
if (fcu->totvert == 1) {
v1[0] = prevbezt->vec[1][0];
v1[1] = prevbezt->vec[1][1];
- glVertex2fv(v1);
+ immVertex2fv(pos, v1);
}
/* draw curve between first and last keyframe (if there are enough to do so) */
@@ -708,17 +722,17 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
/* Constant-Interpolation: draw segment between previous keyframe and next, but holding same value */
v1[0] = prevbezt->vec[1][0];
v1[1] = prevbezt->vec[1][1];
- glVertex2fv(v1);
+ immVertex2fv(pos, v1);
v1[0] = bezt->vec[1][0];
v1[1] = prevbezt->vec[1][1];
- glVertex2fv(v1);
+ immVertex2fv(pos, v1);
}
else if (prevbezt->ipo == BEZT_IPO_LIN) {
/* Linear interpolation: just add one point (which should add a new line segment) */
v1[0] = prevbezt->vec[1][0];
v1[1] = prevbezt->vec[1][1];
- glVertex2fv(v1);
+ immVertex2fv(pos, v1);
}
else if (prevbezt->ipo == BEZT_IPO_BEZ) {
/* Bezier-Interpolation: draw curve as series of segments between keyframes
@@ -738,7 +752,7 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
/* only draw one */
v1[0] = prevbezt->vec[1][0];
v1[1] = prevbezt->vec[1][1];
- glVertex2fv(v1);
+ immVertex2fv(pos, v1);
}
else {
/* clamp resolution to max of 32 */
@@ -760,8 +774,9 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
BKE_curve_forward_diff_bezier(v1[0], v2[0], v3[0], v4[0], data, resol, sizeof(float) * 3);
BKE_curve_forward_diff_bezier(v1[1], v2[1], v3[1], v4[1], data + 1, resol, sizeof(float) * 3);
- for (fp = data; resol; resol--, fp += 3)
- glVertex2fv(fp);
+ for (fp = data; resol; resol--, fp += 3) {
+ immVertex2fv(pos, fp);
+ }
}
}
@@ -773,7 +788,7 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
if (b == 0) {
v1[0] = prevbezt->vec[1][0];
v1[1] = prevbezt->vec[1][1];
- glVertex2fv(v1);
+ immVertex2fv(pos, v1);
}
}
@@ -800,11 +815,12 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
v1[1] = prevbezt->vec[1][1] - fac * (prevbezt->vec[2][1] - prevbezt->vec[1][1]);
}
- glVertex2fv(v1);
+ immVertex2fv(pos, v1);
}
- glEnd();
- glPopMatrix();
+ immEnd();
+
+ gpuPopMatrix();
}
/* Debugging -------------------------------- */
@@ -826,6 +842,15 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu)
//if ((driver->flag & DRIVER_FLAG_SHOWDEBUG) == 0)
// return;
+ const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
+
+ immUniform1i("num_colors", 0); /* Simple dashes. */
+
/* No curve to modify/visualize the result?
* => We still want to show the 1-1 default...
*/
@@ -833,26 +858,24 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu)
float t;
/* draw with thin dotted lines in style of what curve would have been */
- glColor3fv(fcu->color);
+ immUniformColor3fv(fcu->color);
- setlinestyle(20);
+ immUniform1f("dash_width", 40.0f);
+ immUniform1f("dash_factor", 0.5f);
glLineWidth(2.0f);
/* draw 1-1 line, stretching just past the screen limits
* NOTE: we need to scale the y-values to be valid for the units
*/
- glBegin(GL_LINES);
- {
- t = v2d->cur.xmin;
- glVertex2f(t, (t + offset) * unitfac);
+ immBegin(GWN_PRIM_LINES, 2);
- t = v2d->cur.xmax;
- glVertex2f(t, (t + offset) * unitfac);
- }
- glEnd();
+ t = v2d->cur.xmin;
+ immVertex2f(shdr_pos, t, (t + offset) * unitfac);
- /* cleanup line drawing */
- setlinestyle(0);
+ t = v2d->cur.xmax;
+ immVertex2f(shdr_pos, t, (t + offset) * unitfac);
+
+ immEnd();
}
/* draw driver only if actually functional */
@@ -866,53 +889,59 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu)
float co[2];
/* draw dotted lines leading towards this point from both axes ....... */
- glColor3f(0.9f, 0.9f, 0.9f);
- setlinestyle(5);
+ immUniformColor3f(0.9f, 0.9f, 0.9f);
+ immUniform1f("dash_width", 10.0f);
+ immUniform1f("dash_factor", 0.5f);
- glBegin(GL_LINES);
- {
- /* x-axis lookup */
- co[0] = x;
+ immBegin(GWN_PRIM_LINES, (y >= v2d->cur.ymin) ? 4 : 2);
- if (y >= v2d->cur.ymin) {
- co[1] = v2d->cur.ymin - 1.0f;
- glVertex2fv(co);
+ /* x-axis lookup */
+ co[0] = x;
- co[1] = y;
- glVertex2fv(co);
- }
+ if (y >= v2d->cur.ymin) {
+ co[1] = v2d->cur.ymin - 1.0f;
+ immVertex2fv(shdr_pos, co);
- /* y-axis lookup */
co[1] = y;
+ immVertex2fv(shdr_pos, co);
+ }
- co[0] = v2d->cur.xmin - 1.0f;
- glVertex2fv(co);
+ /* y-axis lookup */
+ co[1] = y;
- co[0] = x;
- glVertex2fv(co);
- }
- glEnd();
+ co[0] = v2d->cur.xmin - 1.0f;
+ immVertex2fv(shdr_pos, co);
+
+ co[0] = x;
+ immVertex2fv(shdr_pos, co);
+
+ immEnd();
- setlinestyle(0);
+ immUnbindProgram();
+
+ /* GWN_PRIM_POINTS do not survive dashed line geometry shader... */
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* x marks the spot .................................................... */
/* -> outer frame */
- glColor3f(0.9f, 0.9f, 0.9f);
+ immUniformColor3f(0.9f, 0.9f, 0.9f);
glPointSize(7.0);
- glBegin(GL_POINTS);
- glVertex2f(x, y);
- glEnd();
+ immBegin(GWN_PRIM_POINTS, 1);
+ immVertex2f(shdr_pos, x, y);
+ immEnd();
/* inner frame */
- glColor3f(0.9f, 0.0f, 0.0f);
+ immUniformColor3f(0.9f, 0.0f, 0.0f);
glPointSize(3.0);
- glBegin(GL_POINTS);
- glVertex2f(x, y);
- glEnd();
+ immBegin(GWN_PRIM_POINTS, 1);
+ immVertex2f(shdr_pos, x, y);
+ immEnd();
}
}
+
+ immUnbindProgram();
}
/* Public Curve-Drawing API ---------------- */
@@ -925,29 +954,43 @@ void graph_draw_ghost_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar)
FCurve *fcu;
/* draw with thick dotted lines */
- setlinestyle(10);
glLineWidth(3.0f);
/* anti-aliased lines for less jagged appearance */
- if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) glEnable(GL_LINE_SMOOTH);
+ if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) {
+ glEnable(GL_LINE_SMOOTH);
+ }
glEnable(GL_BLEND);
+ const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
+
+ immUniform1i("num_colors", 0); /* Simple dashes. */
+ immUniform1f("dash_width", 20.0f);
+ immUniform1f("dash_factor", 0.5f);
+
/* the ghost curves are simply sampled F-Curves stored in sipo->ghostCurves */
for (fcu = sipo->ghostCurves.first; fcu; fcu = fcu->next) {
/* set whatever color the curve has set
* - this is set by the function which creates these
* - draw with a fixed opacity of 2
*/
- glColor4f(fcu->color[0], fcu->color[1], fcu->color[2], 0.5f);
+ immUniformColor3fvAlpha(fcu->color, 0.5f);
/* simply draw the stored samples */
- draw_fcurve_curve_samples(ac, NULL, fcu, &ar->v2d);
+ draw_fcurve_curve_samples(ac, NULL, fcu, &ar->v2d, shdr_pos);
}
- /* restore settings */
- setlinestyle(0);
+ immUnbindProgram();
- if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) glDisable(GL_LINE_SMOOTH);
+ if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) {
+ glDisable(GL_LINE_SMOOTH);
+ }
glDisable(GL_BLEND);
}
@@ -975,8 +1018,9 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
/* map keyframes for drawing if scaled F-Curve */
- if (adt)
+ if (adt) {
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
+ }
/* draw curve:
* - curve line may be result of one or more destructive modifiers or just the raw data,
@@ -986,60 +1030,82 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid
*/
/* 1) draw curve line */
+ if (((fcu->modifiers.first) || (fcu->flag & FCURVE_INT_VALUES)) ||
+ (((fcu->bezt) || (fcu->fpt)) && (fcu->totvert)))
{
/* set color/drawing style for curve itself */
+ /* draw active F-Curve thicker than the rest to make it stand out */
+ if (fcu->flag & FCURVE_ACTIVE) {
+ glLineWidth(2.5);
+ }
+ else {
+ glLineWidth(1.0);
+ }
+
+ /* anti-aliased lines for less jagged appearance */
+ if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) {
+ glEnable(GL_LINE_SMOOTH);
+ }
+ glEnable(GL_BLEND);
+
+ const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
+
+ immUniform1i("num_colors", 0); /* Simple dashes. */
+
if (BKE_fcurve_is_protected(fcu)) {
/* protected curves (non editable) are drawn with dotted lines */
- setlinestyle(2);
+ immUniform1f("dash_width", 4.0f);
+ immUniform1f("dash_factor", 0.5f);
+ }
+ else {
+ immUniform1f("dash_factor", 2.0f); /* solid line */
}
+
if (((fcu->grp) && (fcu->grp->flag & AGRP_MUTED)) || (fcu->flag & FCURVE_MUTED)) {
/* muted curves are drawn in a grayish hue */
/* XXX should we have some variations? */
- UI_ThemeColorShade(TH_HEADER, 50);
+ immUniformThemeColorShade(TH_HEADER, 50);
}
else {
/* set whatever color the curve has set
* - unselected curves draw less opaque to help distinguish the selected ones
*/
- glColor4f(fcu->color[0], fcu->color[1], fcu->color[2], fcurve_display_alpha(fcu));
- }
-
- /* draw active F-Curve thicker than the rest to make it stand out */
- if (fcu->flag & FCURVE_ACTIVE) {
- glLineWidth(2.0);
+ immUniformColor3fvAlpha(fcu->color, fcurve_display_alpha(fcu));
}
- else {
- glLineWidth(1.0);
- }
-
- /* anti-aliased lines for less jagged appearance */
- if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) glEnable(GL_LINE_SMOOTH);
- glEnable(GL_BLEND);
/* draw F-Curve */
if ((fcu->modifiers.first) || (fcu->flag & FCURVE_INT_VALUES)) {
/* draw a curve affected by modifiers or only allowed to have integer values
* by sampling it at various small-intervals over the visible region
*/
- draw_fcurve_curve(ac, ale->id, fcu, &ar->v2d, grid);
+ draw_fcurve_curve(ac, ale->id, fcu, &ar->v2d, grid, shdr_pos);
}
else if (((fcu->bezt) || (fcu->fpt)) && (fcu->totvert)) {
/* just draw curve based on defined data (i.e. no modifiers) */
if (fcu->bezt) {
- if (fcurve_can_use_simple_bezt_drawing(fcu))
- draw_fcurve_curve_bezts(ac, ale->id, fcu, &ar->v2d);
- else
- draw_fcurve_curve(ac, ale->id, fcu, &ar->v2d, grid);
+ if (fcurve_can_use_simple_bezt_drawing(fcu)) {
+ draw_fcurve_curve_bezts(ac, ale->id, fcu, &ar->v2d, shdr_pos);
+ }
+ else {
+ draw_fcurve_curve(ac, ale->id, fcu, &ar->v2d, grid, shdr_pos);
+ }
}
else if (fcu->fpt) {
- draw_fcurve_curve_samples(ac, ale->id, fcu, &ar->v2d);
+ draw_fcurve_curve_samples(ac, ale->id, fcu, &ar->v2d, shdr_pos);
}
}
- /* restore settings */
- setlinestyle(0);
+ immUnbindProgram();
- if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) glDisable(GL_LINE_SMOOTH);
+ if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) {
+ glDisable(GL_LINE_SMOOTH);
+ }
glDisable(GL_BLEND);
}
@@ -1047,7 +1113,7 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid
* - if the option to only show controls if the F-Curve is selected is enabled, we must obey this
*/
if (!(sipo->flag & SIPO_SELCUVERTSONLY) || (fcu->flag & FCURVE_SELECTED)) {
- if (fcurve_are_keyframes_usable(fcu) == 0) {
+ if (!fcurve_are_keyframes_usable(fcu) && !(fcu->fpt && fcu->totvert)) {
/* only draw controls if this is the active modifier */
if ((fcu->flag & FCURVE_ACTIVE) && (fcm)) {
switch (fcm->type) {
@@ -1063,9 +1129,9 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid
float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag, &offset);
/* apply unit-scaling to all values via OpenGL */
- glPushMatrix();
- glScalef(1.0f, unit_scale, 1.0f);
- glTranslatef(0.0f, offset, 0.0f);
+ gpuPushMatrix();
+ gpuScale2f(1.0f, unit_scale);
+ gpuTranslate2f(0.0f, offset);
/* set this once and for all - all handles and handle-verts should use the same thickness */
glLineWidth(1.0);
@@ -1080,14 +1146,14 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid
glDisable(GL_BLEND);
}
- draw_fcurve_vertices(sipo, ar, fcu, do_handles, (sipo->flag & SIPO_SELVHANDLESONLY), unit_scale);
+ draw_fcurve_vertices(ar, fcu, do_handles, (sipo->flag & SIPO_SELVHANDLESONLY));
}
else {
/* samples: only draw two indicators at either end as indicators */
draw_fcurve_samples(sipo, ar, fcu);
}
- glPopMatrix();
+ gpuPopMatrix();
}
}
@@ -1163,7 +1229,7 @@ void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar)
y = (float)ACHANNEL_FIRST(ac);
/* set blending again, as may not be set in previous step */
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
for (ale = anim_data.first, i = 0; ale; ale = ale->next, i++) {
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index 0b8e89160b7..26a6e93ba57 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -36,7 +36,7 @@
#include <float.h>
#ifdef WITH_AUDASPACE
-# include AUD_SPECIAL_H
+# include <AUD_Special.h>
#endif
#include "MEM_guardedalloc.h"
@@ -55,13 +55,14 @@
#include "BLT_translation.h"
#include "BKE_context.h"
-#include "BKE_depsgraph.h"
#include "BKE_fcurve.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_nla.h"
#include "BKE_report.h"
+#include "DEG_depsgraph_build.h"
+
#include "UI_view2d.h"
#include "ED_anim_api.h"
@@ -526,6 +527,7 @@ static void insert_graph_keys(bAnimContext *ac, eGraphKeys_InsertKey_Types mode)
ReportList *reports = ac->reports;
SpaceIpo *sipo = (SpaceIpo *)ac->sl;
+ struct Depsgraph *depsgraph = ac->depsgraph;
Scene *scene = ac->scene;
ToolSettings *ts = scene->toolsettings;
short flag = 0;
@@ -608,7 +610,7 @@ static void insert_graph_keys(bAnimContext *ac, eGraphKeys_InsertKey_Types mode)
* up adding the keyframes on a new F-Curve in the action data instead.
*/
if (ale->id && !ale->owner && !fcu->driver) {
- insert_keyframe(ac->bmain, reports, ale->id, NULL, ((fcu->grp) ? (fcu->grp->name) : (NULL)),
+ insert_keyframe(ac->bmain, depsgraph, reports, ale->id, NULL, ((fcu->grp) ? (fcu->grp->name) : (NULL)),
fcu->rna_path, fcu->array_index, cfra, ts->keyframe_type, flag);
}
else {
@@ -2716,7 +2718,7 @@ static int graph_driver_vars_paste_exec(bContext *C, wmOperator *op)
/* successful or not? */
if (ok) {
/* rebuild depsgraph, now that there are extra deps here */
- DAG_relations_tag_update(CTX_data_main(C));
+ DEG_relations_tag_update(CTX_data_main(C));
/* set notifier that keyframes have changed */
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, CTX_data_scene(C));
@@ -2790,7 +2792,7 @@ static int graph_driver_delete_invalid_exec(bContext *C, wmOperator *op)
if (deleted > 0) {
/* notify the world of any changes */
- DAG_relations_tag_update(CTX_data_main(C));
+ DEG_relations_tag_update(CTX_data_main(C));
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_REMOVED, NULL);
WM_reportf(RPT_INFO, "Deleted %u drivers", deleted);
}
diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c
index b90fdd9ac67..bae5798ca21 100644
--- a/source/blender/editors/space_graph/graph_ops.c
+++ b/source/blender/editors/space_graph/graph_ops.c
@@ -614,6 +614,8 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap)
WM_keymap_add_menu(keymap, "GRAPH_MT_delete", XKEY, KM_PRESS, 0, 0);
WM_keymap_add_menu(keymap, "GRAPH_MT_delete", DELKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_menu(keymap, "GRAPH_MT_specials", WKEY, KM_PRESS, 0, 0);
+
WM_keymap_add_item(keymap, "GRAPH_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0);
/* insertkey */
@@ -715,4 +717,3 @@ void graphedit_keymap(wmKeyConfig *keyconf)
keymap = WM_keymap_find(keyconf, "Graph Editor", SPACE_IPO, 0);
graphedit_keymap_keyframes(keyconf, keymap);
}
-
diff --git a/source/blender/editors/space_graph/graph_utils.c b/source/blender/editors/space_graph/graph_utils.c
index f55a5511e2d..e543111e662 100644
--- a/source/blender/editors/space_graph/graph_utils.c
+++ b/source/blender/editors/space_graph/graph_utils.c
@@ -44,17 +44,62 @@
#include "BKE_context.h"
#include "BKE_fcurve.h"
+#include "BKE_screen.h"
#include "WM_api.h"
#include "ED_anim_api.h"
+#include "ED_screen.h"
+#include "UI_interface.h"
#include "graph_intern.h" // own include
/* ************************************************************** */
+/* Set Up Drivers Editor */
+
+/* Set up UI configuration for Drivers Editor */
+/* NOTE: Currently called from windowmanager (new drivers editor window) and RNA (mode switching) */
+void ED_drivers_editor_init(bContext *C, ScrArea *sa)
+{
+ SpaceIpo *sipo = (SpaceIpo *)sa->spacedata.first;
+
+ /* Set mode */
+ sipo->mode = SIPO_MODE_DRIVERS;
+
+ /* Show Properties Region (or else the settings can't be edited) */
+ ARegion *ar_props = BKE_area_find_region_type(sa, RGN_TYPE_UI);
+ if (ar_props) {
+ UI_panel_category_active_set(ar_props, "Drivers");
+
+ ar_props->flag &= ~RGN_FLAG_HIDDEN;
+ /* XXX: Adjust width of this too? */
+
+ ED_region_visibility_change_update(C, ar_props);
+ }
+ else {
+ printf("%s: Couldn't find properties region for Drivers Editor - %p\n", __func__, sa);
+ }
+
+ /* Adjust framing in graph region */
+ /* TODO: Have a way of not resetting this every time?
+ * (e.g. So that switching back and forth between editors doesn't keep jumping?)
+ */
+ ARegion *ar_main = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
+ if (ar_main) {
+ /* XXX: Ideally we recenter based on the range instead... */
+ ar_main->v2d.tot.xmin = -2.0f;
+ ar_main->v2d.tot.ymin = -2.0f;
+ ar_main->v2d.tot.xmax = 2.0f;
+ ar_main->v2d.tot.ymax = 2.0f;
+
+ ar_main->v2d.cur = ar_main->v2d.tot;
+ }
+}
+
+/* ************************************************************** */
/* Active F-Curve */
/* Find 'active' F-Curve. It must be editable, since that's the purpose of these buttons (subject to change).
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index 383c2b5b220..7c3105843c5 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -53,10 +53,15 @@
#include "ED_anim_api.h"
#include "ED_markers.h"
-#include "BIF_gl.h"
+#include "GPU_immediate.h"
#include "WM_api.h"
#include "WM_types.h"
+#include "WM_message.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
#include "UI_resources.h"
#include "UI_view2d.h"
@@ -92,9 +97,8 @@ ARegion *graph_has_buttons_region(ScrArea *sa)
/* ******************** default callbacks for ipo space ***************** */
-static SpaceLink *graph_new(const bContext *C)
+static SpaceLink *graph_new(const ScrArea *UNUSED(sa), const Scene *scene)
{
- Scene *scene = CTX_data_scene(C);
ARegion *ar;
SpaceIpo *sipo;
@@ -117,7 +121,7 @@ static SpaceLink *graph_new(const bContext *C)
BLI_addtail(&sipo->regionbase, ar);
ar->regiontype = RGN_TYPE_HEADER;
- ar->alignment = RGN_ALIGN_BOTTOM;
+ ar->alignment = RGN_ALIGN_TOP;
/* channels */
ar = MEM_callocN(sizeof(ARegion), "channels region for graphedit");
@@ -179,14 +183,14 @@ static void graph_free(SpaceLink *sl)
/* spacetype; init callback */
-static void graph_init(struct wmWindowManager *UNUSED(wm), ScrArea *sa)
+static void graph_init(struct wmWindowManager *wm, ScrArea *sa)
{
SpaceIpo *sipo = (SpaceIpo *)sa->spacedata.first;
/* init dopesheet data if non-existent (i.e. for old files) */
if (sipo->ads == NULL) {
sipo->ads = MEM_callocN(sizeof(bDopeSheet), "GraphEdit DopeSheet");
- sipo->ads->source = (ID *)(G.main->scene.first); // FIXME: this is a really nasty hack here for now...
+ sipo->ads->source = (ID *)WM_window_get_active_scene(wm->winactive);
}
/* force immediate init of any invalid F-Curve colors */
@@ -226,12 +230,13 @@ static void graph_main_region_draw(const bContext *C, ARegion *ar)
{
/* draw entirely, view changes should be handled here */
SpaceIpo *sipo = CTX_wm_space_graph(C);
+ Scene *scene = CTX_data_scene(C);
bAnimContext ac;
View2D *v2d = &ar->v2d;
View2DGrid *grid;
View2DScrollers *scrollers;
float col[3];
- short unitx = 0, unity = V2D_UNIT_VALUES, flag = 0;
+ short unitx = 0, unity = V2D_UNIT_VALUES, cfra_flag = 0;
/* clear and setup matrix */
UI_GetThemeColor3fv(TH_BACK, col);
@@ -247,6 +252,11 @@ static void graph_main_region_draw(const bContext *C, ARegion *ar)
ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
+ /* start and end frame (in F-Curve mode only) */
+ if (sipo->mode != SIPO_MODE_DRIVERS) {
+ ANIM_draw_framerange(scene, v2d);
+ }
+
/* draw data */
if (ANIM_animdata_get_context(C, &ac)) {
/* draw ghost curves */
@@ -266,46 +276,53 @@ static void graph_main_region_draw(const bContext *C, ARegion *ar)
/* only free grid after drawing data, as we need to use it to determine sampling rate */
UI_view2d_grid_free(grid);
- /* horizontal component of value-cursor (value line before the current frame line) */
- if ((sipo->flag & SIPO_NODRAWCURSOR) == 0) {
+ if (((sipo->flag & SIPO_NODRAWCURSOR) == 0) || (sipo->mode == SIPO_MODE_DRIVERS)) {
+ unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- float y = sipo->cursorVal;
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- /* Draw a green line to indicate the cursor value */
- UI_ThemeColorShadeAlpha(TH_CFRAME, -10, -50);
- glEnable(GL_BLEND);
- glLineWidth(2.0);
+ /* horizontal component of value-cursor (value line before the current frame line) */
+ if ((sipo->flag & SIPO_NODRAWCURSOR) == 0) {
+ float y = sipo->cursorVal;
- glBegin(GL_LINES);
- glVertex2f(v2d->cur.xmin, y);
- glVertex2f(v2d->cur.xmax, y);
- glEnd();
+ /* Draw a green line to indicate the cursor value */
+ immUniformThemeColorShadeAlpha(TH_CFRAME, -10, -50);
+ glEnable(GL_BLEND);
+ glLineWidth(2.0);
- glDisable(GL_BLEND);
- }
+ immBegin(GWN_PRIM_LINES, 2);
+ immVertex2f(pos, v2d->cur.xmin, y);
+ immVertex2f(pos, v2d->cur.xmax, y);
+ immEnd();
+
+ glDisable(GL_BLEND);
+ }
+
+ /* current frame or vertical component of vertical component of the cursor */
+ if (sipo->mode == SIPO_MODE_DRIVERS) {
+ /* cursor x-value */
+ float x = sipo->cursorTime;
- /* current frame or vertical component of vertical component of the cursor */
- if (sipo->mode == SIPO_MODE_DRIVERS) {
- /* cursor x-value */
- float x = sipo->cursorTime;
+ /* to help differentiate this from the current frame, draw slightly darker like the horizontal one */
+ immUniformThemeColorShadeAlpha(TH_CFRAME, -40, -50);
+ glEnable(GL_BLEND);
+ glLineWidth(2.0);
- /* to help differentiate this from the current frame, draw slightly darker like the horizontal one */
- UI_ThemeColorShadeAlpha(TH_CFRAME, -40, -50);
- glEnable(GL_BLEND);
- glLineWidth(2.0);
+ immBegin(GWN_PRIM_LINES, 2);
+ immVertex2f(pos, x, v2d->cur.ymin);
+ immVertex2f(pos, x, v2d->cur.ymax);
+ immEnd();
- glBegin(GL_LINES);
- glVertex2f(x, v2d->cur.ymin);
- glVertex2f(x, v2d->cur.ymax);
- glEnd();
+ glDisable(GL_BLEND);
+ }
- glDisable(GL_BLEND);
+ immUnbindProgram();
}
- else {
+
+ if (sipo->mode != SIPO_MODE_DRIVERS) {
/* current frame */
- if (sipo->flag & SIPO_DRAWTIME) flag |= DRAWCFRA_UNIT_SECONDS;
- if ((sipo->flag & SIPO_NODRAWCFRANUM) == 0) flag |= DRAWCFRA_SHOW_NUMBOX;
- ANIM_draw_cfra(C, v2d, flag);
+ if (sipo->flag & SIPO_DRAWTIME) cfra_flag |= DRAWCFRA_UNIT_SECONDS;
+ ANIM_draw_cfra(C, v2d, cfra_flag);
}
/* markers */
@@ -328,6 +345,12 @@ static void graph_main_region_draw(const bContext *C, ARegion *ar)
scrollers = UI_view2d_scrollers_calc(C, v2d, unitx, V2D_GRID_NOCLAMP, unity, V2D_GRID_NOCLAMP);
UI_view2d_scrollers_draw(C, v2d, scrollers);
UI_view2d_scrollers_free(scrollers);
+
+ /* draw current frame number-indicator on top of scrollers */
+ if ((sipo->mode != SIPO_MODE_DRIVERS) && ((sipo->flag & SIPO_NODRAWCFRANUM) == 0)) {
+ UI_view2d_view_orthoSpecial(ar, v2d, 1);
+ ANIM_draw_cfra_number(C, v2d, cfra_flag);
+ }
}
static void graph_channel_region_init(wmWindowManager *wm, ARegion *ar)
@@ -401,10 +424,12 @@ static void graph_buttons_region_init(wmWindowManager *wm, ARegion *ar)
static void graph_buttons_region_draw(const bContext *C, ARegion *ar)
{
- ED_region_panels(C, ar, NULL, -1, true);
+ ED_region_panels(C, ar);
}
-static void graph_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void graph_region_listener(
+ bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
+ wmNotifier *wmn, const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
@@ -416,6 +441,7 @@ static void graph_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), AReg
case ND_RENDER_OPTIONS:
case ND_OB_ACTIVE:
case ND_FRAME:
+ case ND_FRAME_RANGE:
case ND_MARKERS:
ED_region_tag_redraw(ar);
break;
@@ -450,6 +476,11 @@ static void graph_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), AReg
if (wmn->action == NA_RENAME)
ED_region_tag_redraw(ar);
break;
+ case NC_SCREEN:
+ if (ELEM(wmn->data, ND_LAYER)) {
+ ED_region_tag_redraw(ar);
+ }
+ break;
default:
if (wmn->data == ND_KEYS)
ED_region_tag_redraw(ar);
@@ -458,8 +489,85 @@ static void graph_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), AReg
}
}
+static void graph_region_message_subscribe(
+ const struct bContext *UNUSED(C),
+ struct WorkSpace *UNUSED(workspace), struct Scene *scene,
+ struct bScreen *screen, struct ScrArea *sa, struct ARegion *ar,
+ struct wmMsgBus *mbus)
+{
+ PointerRNA ptr;
+ RNA_pointer_create(&screen->id, &RNA_SpaceGraphEditor, sa->spacedata.first, &ptr);
+
+ wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
+ .owner = ar,
+ .user_data = ar,
+ .notify = ED_region_do_msg_notify_tag_redraw,
+ };
+
+ /* Timeline depends on scene properties. */
+ {
+ bool use_preview = (scene->r.flag & SCER_PRV_RANGE);
+ extern PropertyRNA rna_Scene_frame_start;
+ extern PropertyRNA rna_Scene_frame_end;
+ extern PropertyRNA rna_Scene_frame_preview_start;
+ extern PropertyRNA rna_Scene_frame_preview_end;
+ extern PropertyRNA rna_Scene_use_preview_range;
+ extern PropertyRNA rna_Scene_frame_current;
+ const PropertyRNA *props[] = {
+ use_preview ? &rna_Scene_frame_preview_start : &rna_Scene_frame_start,
+ use_preview ? &rna_Scene_frame_preview_end : &rna_Scene_frame_end,
+ &rna_Scene_use_preview_range,
+ &rna_Scene_frame_current,
+ };
+
+ PointerRNA idptr;
+ RNA_id_pointer_create(&scene->id, &idptr);
+
+ for (int i = 0; i < ARRAY_SIZE(props); i++) {
+ WM_msg_subscribe_rna(mbus, &idptr, props[i], &msg_sub_value_region_tag_redraw, __func__);
+ }
+ }
+
+ /* All dopesheet filter settings, etc. affect the drawing of this editor,
+ * also same applies for all animation-related datatypes that may appear here,
+ * so just whitelist the entire structs for updates
+ */
+ {
+ wmMsgParams_RNA msg_key_params = {{{0}}};
+ StructRNA *type_array[] = {
+ &RNA_DopeSheet, /* dopesheet filters */
+
+ &RNA_ActionGroup, /* channel groups */
+ &RNA_FCurve, /* F-Curve */
+ &RNA_Keyframe,
+ &RNA_FCurveSample,
+
+ &RNA_FModifier, /* F-Modifiers (XXX: Why can't we just do all subclasses too?) */
+ &RNA_FModifierCycles,
+ &RNA_FModifierEnvelope,
+ &RNA_FModifierEnvelopeControlPoint,
+ &RNA_FModifierFunctionGenerator,
+ &RNA_FModifierGenerator,
+ &RNA_FModifierLimits,
+ &RNA_FModifierNoise,
+ &RNA_FModifierPython,
+ &RNA_FModifierStepped,
+ };
+
+ for (int i = 0; i < ARRAY_SIZE(type_array); i++) {
+ msg_key_params.ptr.type = type_array[i];
+ WM_msg_subscribe_rna_params(
+ mbus,
+ &msg_key_params,
+ &msg_sub_value_region_tag_redraw,
+ __func__);
+ }
+ }
+}
+
/* editor level listener */
-static void graph_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn)
+static void graph_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, Scene *UNUSED(scene),
+ WorkSpace *UNUSED(workspace))
{
SpaceIpo *sipo = (SpaceIpo *)sa->spacedata.first;
@@ -685,7 +793,7 @@ static void graph_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID
if (sgraph->ads) {
if ((ID *)sgraph->ads->filter_grp == old_id) {
- sgraph->ads->filter_grp = (Group *)new_id;
+ sgraph->ads->filter_grp = (Collection *)new_id;
}
if ((ID *)sgraph->ads->source == old_id) {
sgraph->ads->source = new_id;
@@ -693,6 +801,24 @@ static void graph_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID
}
}
+static int graph_space_subtype_get(ScrArea *sa)
+{
+ SpaceIpo *sgraph = sa->spacedata.first;
+ return sgraph->mode;
+}
+
+static void graph_space_subtype_set(ScrArea *sa, int value)
+{
+ SpaceIpo *sgraph = sa->spacedata.first;
+ sgraph->mode = value;
+}
+
+static void graph_space_subtype_item_extend(
+ bContext *UNUSED(C), EnumPropertyItem **item, int *totitem)
+{
+ RNA_enum_items_add(item, totitem, rna_enum_space_graph_mode_items);
+}
+
/* only called once, from space/spacetypes.c */
void ED_spacetype_ipo(void)
{
@@ -711,6 +837,9 @@ void ED_spacetype_ipo(void)
st->listener = graph_listener;
st->refresh = graph_refresh;
st->id_remap = graph_id_remap;
+ st->space_subtype_item_extend = graph_space_subtype_item_extend;
+ st->space_subtype_get = graph_space_subtype_get;
+ st->space_subtype_set = graph_space_subtype_set;
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype graphedit region");
@@ -718,6 +847,7 @@ void ED_spacetype_ipo(void)
art->init = graph_main_region_init;
art->draw = graph_main_region_draw;
art->listener = graph_region_listener;
+ art->message_subscribe = graph_region_message_subscribe;
art->keymapflag = ED_KEYMAP_VIEW2D | ED_KEYMAP_MARKERS | ED_KEYMAP_ANIMATION | ED_KEYMAP_FRAMES;
BLI_addhead(&st->regiontypes, art);
@@ -739,6 +869,7 @@ void ED_spacetype_ipo(void)
art->prefsizex = 200 + V2D_SCROLL_WIDTH; /* 200 is the 'standard', but due to scrollers, we want a bit more to fit the lock icons in */
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES;
art->listener = graph_region_listener;
+ art->message_subscribe = graph_region_message_subscribe;
art->init = graph_channel_region_init;
art->draw = graph_channel_region_draw;
@@ -759,4 +890,3 @@ void ED_spacetype_ipo(void)
BKE_spacetype_register(st);
}
-