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
path: root/source
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2013-10-12 18:09:05 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2013-10-12 18:09:05 +0400
commitd7983e3638896e5742fcf1bafe49c49a6b0aa08f (patch)
tree99470c4aa0896751b9955b5bdb3d3979db73aa91 /source
parentf0dcff9aa982d32bcb91e594df49a780ac376b5b (diff)
Option to overlay mask over the footage
Currently supports only two modes: - Show alpha channel of the mask - Multiply footage by the mask, which will give you final-looking combined image. TODO: Currently rasterization happens on every redraw, need to cache rasterized mask somewhere to make redraw more realtime.
Diffstat (limited to 'source')
-rw-r--r--source/blender/editors/include/ED_mask.h2
-rw-r--r--source/blender/editors/mask/mask_draw.c118
-rw-r--r--source/blender/editors/screen/glutil.c2
-rw-r--r--source/blender/editors/space_clip/space_clip.c4
-rw-r--r--source/blender/editors/space_image/space_image.c7
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c2
-rw-r--r--source/blender/makesdna/DNA_mask_types.h7
-rw-r--r--source/blender/makesdna/DNA_space_types.h3
-rw-r--r--source/blender/makesrna/intern/rna_space.c17
9 files changed, 154 insertions, 8 deletions
diff --git a/source/blender/editors/include/ED_mask.h b/source/blender/editors/include/ED_mask.h
index 3e2dbe255df..8da36f015dc 100644
--- a/source/blender/editors/include/ED_mask.h
+++ b/source/blender/editors/include/ED_mask.h
@@ -57,7 +57,7 @@ void ED_operatormacros_mask(void);
/* mask_draw.c */
void ED_mask_draw(const struct bContext *C, const char draw_flag, const char draw_type);
void ED_mask_draw_region(struct Mask *mask, struct ARegion *ar,
- const char draw_flag, const char draw_type,
+ const char draw_flag, const char draw_type, const char overlay_mode,
const int width_i, const int height_i,
const float aspx, const float aspy,
const short do_scale_applied, const short do_draw_cb,
diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c
index fec4ab87996..50d8e653737 100644
--- a/source/blender/editors/mask/mask_draw.c
+++ b/source/blender/editors/mask/mask_draw.c
@@ -35,6 +35,7 @@
#include "BLI_utildefines.h"
#include "BLI_math.h"
#include "BLI_rect.h"
+#include "BLI_task.h"
#include "BKE_context.h"
#include "BKE_mask.h"
@@ -48,6 +49,7 @@
#include "ED_mask.h" /* own include */
#include "ED_space_api.h"
#include "BIF_gl.h"
+#include "BIF_glutil.h"
#include "UI_resources.h"
#include "UI_view2d.h"
@@ -535,10 +537,93 @@ void ED_mask_draw(const bContext *C,
draw_masklays(C, mask, draw_flag, draw_type, width, height);
}
+typedef struct ThreadedMaskRasterizeState {
+ MaskRasterHandle *handle;
+ float *buffer;
+ int width, height;
+} ThreadedMaskRasterizeState;
+
+typedef struct ThreadedMaskRasterizeData {
+ int start_scanline;
+ int num_scanlines;
+} ThreadedMaskRasterizeData;
+
+static void mask_rasterize_func(TaskPool *pool, void *taskdata, int UNUSED(threadid))
+{
+ ThreadedMaskRasterizeState *state = (ThreadedMaskRasterizeState *) BLI_task_pool_userdata(pool);
+ ThreadedMaskRasterizeData *data = (ThreadedMaskRasterizeData *) taskdata;
+ int scanline;
+
+ for (scanline = 0; scanline < data->num_scanlines; scanline++) {
+ int x, y = data->start_scanline + scanline;
+ for (x = 0; x < state->width; x++) {
+ int index = y * state->width + x;
+ float xy[2];
+
+ xy[0] = (float) x / state->width;
+ xy[1] = (float) y / state->height;
+
+ state->buffer[index] = BKE_maskrasterize_handle_sample(state->handle, xy);
+ }
+ }
+}
+
+static float *threaded_mask_rasterize(Mask *mask, const int width, const int height)
+{
+ TaskScheduler *task_scheduler = BLI_task_scheduler_get();
+ TaskPool *task_pool;
+ MaskRasterHandle *handle;
+ ThreadedMaskRasterizeState state;
+ float *buffer;
+ int i, num_threads = BLI_task_scheduler_num_threads(task_scheduler), scanlines_per_thread;
+
+ buffer = MEM_mallocN(sizeof(float) * height * width, "rasterized mask buffer");
+
+ /* Initialize rasterization handle. */
+ handle = BKE_maskrasterize_handle_new();
+ BKE_maskrasterize_handle_init(handle, mask, width, height, TRUE, TRUE, TRUE);
+
+ state.handle = handle;
+ state.buffer = buffer;
+ state.width = width;
+ state.height = height;
+
+ task_pool = BLI_task_pool_create(task_scheduler, &state);
+
+ BLI_begin_threaded_malloc();
+
+ scanlines_per_thread = height / num_threads;
+ for (i = 0; i < num_threads; i++) {
+ ThreadedMaskRasterizeData *data = MEM_mallocN(sizeof(ThreadedMaskRasterizeData),
+ "threaded mask rasterize data");
+
+ data->start_scanline = i * scanlines_per_thread;
+
+ if (i < num_threads - 1) {
+ data->num_scanlines = scanlines_per_thread;
+ }
+ else {
+ data->num_scanlines = height - data->start_scanline;
+ }
+
+ BLI_task_pool_push(task_pool, mask_rasterize_func, data, true, TASK_PRIORITY_LOW);
+ }
+
+ /* work and wait until tasks are done */
+ BLI_task_pool_work_and_wait(task_pool);
+
+ /* Free memory. */
+ BLI_task_pool_free(task_pool);
+ BLI_end_threaded_malloc();
+ BKE_maskrasterize_handle_free(handle);
+
+ return buffer;
+}
+
/* sets up the opengl context.
* width, height are to match the values from ED_mask_get_size() */
void ED_mask_draw_region(Mask *mask, ARegion *ar,
- const char draw_flag, const char draw_type,
+ const char draw_flag, const char draw_type, const char overlay_mode,
const int width_i, const int height_i, /* convert directly into aspect corrected vars */
const float aspx, const float aspy,
const short do_scale_applied, const short do_draw_cb,
@@ -592,6 +677,37 @@ void ED_mask_draw_region(Mask *mask, ARegion *ar,
yofs = ((width - height) / -2.0f) * zoomy;
}
+ if (draw_flag & MASK_DRAWFLAG_OVERLAY) {
+ float *buffer = threaded_mask_rasterize(mask, width, height);
+ int format;
+
+ if (overlay_mode == MASK_OVERLAY_ALPHACHANNEL) {
+ glColor3f(1.0f, 1.0f, 1.0f);
+ format = GL_LUMINANCE;
+ }
+ else {
+ /* More blending types could be supported in the future. */
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_DST_COLOR, GL_SRC_ALPHA);
+ format = GL_ALPHA;
+ }
+
+ glPushMatrix();
+ glTranslatef(x, y, 0);
+ glScalef(zoomx, zoomy, 0);
+ if (stabmat) {
+ glMultMatrixf(stabmat);
+ }
+ glaDrawPixelsTex(0.0f, 0.0f, width, height, format, GL_FLOAT, GL_NEAREST, buffer);
+ glPopMatrix();
+
+ if (overlay_mode != MASK_OVERLAY_ALPHACHANNEL) {
+ glDisable(GL_BLEND);
+ }
+
+ MEM_freeN(buffer);
+ }
+
/* apply transformation so mask editing tools will assume drawing from the origin in normalized space */
glPushMatrix();
glTranslatef(x + xofs, y + yofs, 0);
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index b70b06f2aa4..d356c3d8de3 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -531,7 +531,7 @@ void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format,
components = 4;
else if (format == GL_RGB)
components = 3;
- else if (format == GL_LUMINANCE)
+ else if (ELEM(format, GL_LUMINANCE, GL_ALPHA))
components = 1;
else {
BLI_assert(!"Incompatible format passed to glaDrawPixelsTexScaled");
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index 3ede63adb72..adc902bf4ba 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -1191,7 +1191,9 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar)
int mask_width, mask_height;
ED_mask_get_size(sa, &mask_width, &mask_height);
ED_mask_draw_region(mask, ar,
- sc->mask_info.draw_flag, sc->mask_info.draw_type,
+ sc->mask_info.draw_flag,
+ sc->mask_info.draw_type,
+ sc->mask_info.overlay_mode,
mask_width, mask_height,
aspx, aspy,
TRUE, TRUE,
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index 5a8292abcab..7b20af340ae 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -674,7 +674,6 @@ static void image_main_area_draw(const bContext *C, ARegion *ar)
}
else if (sima->mode == SI_MODE_MASK) {
mask = ED_space_image_get_mask(sima);
- draw_image_cursor(ar, sima->cursor);
}
ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
@@ -715,7 +714,9 @@ static void image_main_area_draw(const bContext *C, ARegion *ar)
BLI_unlock_thread(LOCK_DRAW_IMAGE);
ED_mask_draw_region(mask, ar,
- sima->mask_info.draw_flag, sima->mask_info.draw_type,
+ sima->mask_info.draw_flag,
+ sima->mask_info.draw_type,
+ sima->mask_info.overlay_mode,
width, height,
aspx, aspy,
TRUE, FALSE,
@@ -723,7 +724,9 @@ static void image_main_area_draw(const bContext *C, ARegion *ar)
ED_mask_draw_frames(mask, ar, CFRA, mask->sfra, mask->efra);
+ UI_view2d_view_ortho(v2d);
draw_image_cursor(ar, sima->cursor);
+ UI_view2d_view_restore(C);
}
/* scrollers? */
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index dca1b481334..cb69a7fe654 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -1251,7 +1251,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
height = (scene->r.size * scene->r.ysch) / 100;
ED_mask_draw_region(mask, ar,
- 0, 0, /* TODO */
+ 0, 0, 0, /* TODO */
width, height,
aspx, aspy,
FALSE, TRUE,
diff --git a/source/blender/makesdna/DNA_mask_types.h b/source/blender/makesdna/DNA_mask_types.h
index 4307ea57f15..a72e287c16f 100644
--- a/source/blender/makesdna/DNA_mask_types.h
+++ b/source/blender/makesdna/DNA_mask_types.h
@@ -178,6 +178,7 @@ enum {
/* SpaceClip->mask_draw_flag */
#define MASK_DRAWFLAG_SMOOTH 1
+#define MASK_DRAWFLAG_OVERLAY 2
/* copy of eSpaceImage_UVDT */
/* SpaceClip->mask_draw_type */
@@ -188,6 +189,12 @@ enum {
MASK_DT_WHITE = 3
};
+/* MaskSpaceInfo->overlay_mode */
+enum {
+ MASK_OVERLAY_ALPHACHANNEL = 0,
+ MASK_OVERLAY_COMBINED = 1
+};
+
/* masklay->blend */
enum {
MASK_BLEND_ADD = 0,
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 0478ff567a0..5befaa87e7f 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -546,7 +546,8 @@ typedef struct MaskSpaceInfo
/* draw options */
char draw_flag;
char draw_type;
- char pad3[6];
+ char overlay_mode;
+ char pad3[5];
} MaskSpaceInfo;
/* sseq->mainb */
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index aee6b060221..41ea74ebb8c 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -1336,6 +1336,12 @@ static void rna_def_space_mask_info(StructRNA *srna, int noteflag, const char *m
{
PropertyRNA *prop;
+ static EnumPropertyItem overlay_mode_items[] = {
+ {MASK_OVERLAY_ALPHACHANNEL, "ALPHACHANNEL", ICON_NONE, "Alpha Channel", "Show alpha channel of the mask"},
+ {MASK_OVERLAY_COMBINED, "COMBINED", ICON_NONE, "Combined", "Combine space background image with the mask"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
prop = RNA_def_property(srna, "mask", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "mask_info.mask");
RNA_def_property_flag(prop, PROP_EDITABLE);
@@ -1354,6 +1360,17 @@ static void rna_def_space_mask_info(StructRNA *srna, int noteflag, const char *m
RNA_def_property_boolean_sdna(prop, NULL, "mask_info.draw_flag", MASK_DRAWFLAG_SMOOTH);
RNA_def_property_ui_text(prop, "Draw Smooth Splines", "");
RNA_def_property_update(prop, noteflag, NULL);
+
+ prop = RNA_def_property(srna, "show_mask_overlay", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "mask_info.draw_flag", MASK_DRAWFLAG_OVERLAY);
+ RNA_def_property_ui_text(prop, "Show Mask Overlay", "");
+ RNA_def_property_update(prop, noteflag, NULL);
+
+ prop = RNA_def_property(srna, "mask_overlay_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "mask_info.overlay_mode");
+ RNA_def_property_enum_items(prop, overlay_mode_items);
+ RNA_def_property_ui_text(prop, "Overlay Mode", "Overlay mode of rasterized mask");
+ RNA_def_property_update(prop, noteflag, NULL);
}
static void rna_def_space_image_uv(BlenderRNA *brna)