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_clip/clip_editor.c')
-rw-r--r--source/blender/editors/space_clip/clip_editor.c244
1 files changed, 241 insertions, 3 deletions
diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c
index 3946d4cc36d..bd34a51819c 100644
--- a/source/blender/editors/space_clip/clip_editor.c
+++ b/source/blender/editors/space_clip/clip_editor.c
@@ -31,15 +31,20 @@
#include <stddef.h>
+#include "MEM_guardedalloc.h"
+
#include "BKE_main.h"
#include "BKE_movieclip.h"
#include "BKE_context.h"
#include "BKE_tracking.h"
+
#include "DNA_object_types.h" /* SELECT */
#include "BLI_utildefines.h"
#include "BLI_math.h"
+#include "GPU_extensions.h"
+
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
@@ -47,6 +52,7 @@
#include "ED_clip.h"
#include "BIF_gl.h"
+#include "BIF_glutil.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -55,6 +61,8 @@
#include "clip_intern.h" // own include
+/* ******** operactor poll functions ******** */
+
int ED_space_clip_poll(bContext *C)
{
SpaceClip *sc = CTX_wm_space_clip(C);
@@ -65,13 +73,94 @@ int ED_space_clip_poll(bContext *C)
return FALSE;
}
-void ED_space_clip_set(bContext *C, SpaceClip *sc, MovieClip *clip)
+int ED_space_clip_view_clip_poll(bContext *C)
+{
+ SpaceClip *sc = CTX_wm_space_clip(C);
+
+ if (sc && sc->clip) {
+ return sc->view == SC_VIEW_CLIP;
+ }
+
+ return FALSE;
+}
+
+int ED_space_clip_tracking_poll(bContext *C)
+{
+ SpaceClip *sc = CTX_wm_space_clip(C);
+
+ if (sc && sc->clip)
+ return ED_space_clip_show_trackedit(sc);
+
+ return FALSE;
+}
+
+int ED_space_clip_tracking_size_poll(bContext *C)
+{
+ if (ED_space_clip_tracking_poll(C)) {
+ MovieClip *clip = CTX_data_edit_movieclip(C);
+
+ if (clip) {
+ SpaceClip *sc = CTX_wm_space_clip(C);
+ int width, height;
+
+ BKE_movieclip_get_size(clip, &sc->user, &width, &height);
+
+ return width > 0 && height > 0;
+ }
+ }
+
+ return FALSE;
+}
+
+int ED_space_clip_tracking_frame_poll(bContext *C)
+{
+ if (ED_space_clip_tracking_poll(C)) {
+ MovieClip *clip = CTX_data_edit_movieclip(C);
+
+ if (clip) {
+ SpaceClip *sc = CTX_wm_space_clip(C);
+
+ return BKE_movieclip_has_frame(clip, &sc->user);
+ }
+ }
+
+ return FALSE;
+}
+
+/* ******** editing functions ******** */
+
+void ED_space_clip_set(bContext *C, bScreen *screen, SpaceClip *sc, MovieClip *clip)
{
+ MovieClip *old_clip;
+
+ if (!screen && C)
+ screen = CTX_wm_screen(C);
+
+ old_clip = sc->clip;
sc->clip = clip;
- if (sc->clip && sc->clip->id.us==0)
+ if (sc->clip && sc->clip->id.us == 0)
sc->clip->id.us = 1;
+ if (screen) {
+ ScrArea *area;
+ SpaceLink *sl;
+
+ for (area = screen->areabase.first; area; area = area->next) {
+ for (sl = area->spacedata.first; sl; sl = sl->next) {
+ if (sl->spacetype == SPACE_CLIP) {
+ SpaceClip *cur_sc = (SpaceClip *) sl;
+
+ if (cur_sc != sc) {
+ if (cur_sc->clip == old_clip || cur_sc->clip == NULL) {
+ cur_sc->clip = clip;
+ }
+ }
+ }
+ }
+ }
+ }
+
if (C)
WM_event_add_notifier(C, NC_MOVIECLIP|NA_SELECTED, sc->clip);
}
@@ -173,7 +262,7 @@ static int selected_boundbox(SpaceClip *sc, float min[2], float max[2])
MovieClip *clip = ED_space_clip(sc);
MovieTrackingTrack *track;
int width, height, ok = FALSE;
- ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking);
+ ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking);
INIT_MINMAX2(min, max);
@@ -314,3 +403,152 @@ void ED_clip_mouse_pos(bContext *C, wmEvent *event, float co[2])
{
ED_clip_point_stable_pos(C, event->mval[0], event->mval[1], &co[0], &co[1]);
}
+
+/* OpenGL draw context */
+
+typedef struct SpaceClipDrawContext {
+ int support_checked, buffers_supported;
+
+ GLuint texture; /* OGL texture ID */
+ short texture_allocated; /* flag if texture was allocated by glGenTextures */
+ struct ImBuf *texture_ibuf; /* image buffer for which texture was created */
+ int image_width, image_height; /* image width and height for which texture was created */
+ unsigned last_texture; /* ID of previously used texture, so it'll be restored after clip drawing */
+ int framenr;
+} SpaceClipDrawContext;
+
+int ED_space_clip_texture_buffer_supported(SpaceClip *sc)
+{
+ SpaceClipDrawContext *context = sc->draw_context;
+
+ if (!context) {
+ context = MEM_callocN(sizeof(SpaceClipDrawContext), "SpaceClipDrawContext");
+ sc->draw_context = context;
+ }
+
+ if (!context->support_checked) {
+ context->support_checked = TRUE;
+ if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY)) {
+ context->buffers_supported = FALSE;
+ }
+ else {
+ context->buffers_supported = GPU_non_power_of_two_support();
+ }
+ }
+
+ return context->buffers_supported;
+}
+
+int ED_space_clip_load_movieclip_buffer(SpaceClip *sc, ImBuf *ibuf)
+{
+ SpaceClipDrawContext *context = sc->draw_context;
+ MovieClip *clip = ED_space_clip(sc);
+ int need_rebind = 0;
+
+ context->last_texture = glaGetOneInteger(GL_TEXTURE_2D);
+
+ /* image texture need to be rebinded if displaying another image buffer
+ * assuming displaying happens of footage frames only on which painting doesn't heppen.
+ * so not changed image buffer pointer means unchanged image content */
+ need_rebind |= context->texture_ibuf != ibuf;
+ need_rebind |= context->framenr != sc->user.framenr;
+
+ if (need_rebind) {
+ int width = ibuf->x, height = ibuf->y;
+ float *frect = NULL, *fscalerect = NULL;
+ unsigned int *rect = NULL, *scalerect = NULL;
+ int need_recreate = 0;
+
+ if (width > GL_MAX_TEXTURE_SIZE || height > GL_MAX_TEXTURE_SIZE)
+ return 0;
+
+ rect = ibuf->rect;
+ frect = ibuf->rect_float;
+
+ /* if image resolution changed (e.g. switched to proxy display) texture need to be recreated */
+ need_recreate = context->image_width != ibuf->x || context->image_height != ibuf->y;
+
+ if (context->texture_ibuf && need_recreate) {
+ glDeleteTextures(1, &context->texture);
+ context->texture_allocated = 0;
+ }
+
+ if (need_recreate || !context->texture_allocated) {
+ /* texture doesn't exist yet or need to be re-allocated because of changed dimensions */
+ int filter = GL_LINEAR;
+
+ /* non-scaled proxy shouldn;t use diltering */
+ if ((clip->flag & MCLIP_USE_PROXY) == 0 ||
+ ELEM(sc->user.render_size, MCLIP_PROXY_RENDER_SIZE_FULL, MCLIP_PROXY_RENDER_SIZE_100))
+ {
+ filter = GL_NEAREST;
+ }
+
+ glGenTextures(1, &context->texture);
+ glBindTexture(GL_TEXTURE_2D, context->texture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ }
+ else {
+ /* if texture doesn't need to be reallocated itself, just bind it so
+ * loading of image will happen to a proper texture */
+ glBindTexture(GL_TEXTURE_2D, context->texture);
+ }
+
+ if (frect)
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, width, height, 0, GL_RGBA, GL_FLOAT, frect);
+ else
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, rect);
+
+ /* store settings */
+ context->texture_allocated = 1;
+ context->texture_ibuf = ibuf;
+ context->image_width = ibuf->x;
+ context->image_height = ibuf->y;
+ context->framenr = sc->user.framenr;
+
+ if (fscalerect)
+ MEM_freeN(fscalerect);
+ if (scalerect)
+ MEM_freeN(scalerect);
+ }
+ else {
+ /* displaying exactly the same image which was loaded t oa texture,
+ * just bint texture in this case */
+ glBindTexture(GL_TEXTURE_2D, context->texture);
+ }
+
+ glEnable(GL_TEXTURE_2D);
+
+ return TRUE;
+}
+
+void ED_space_clip_unload_movieclip_buffer(SpaceClip *sc)
+{
+ SpaceClipDrawContext *context = sc->draw_context;
+
+ glBindTexture(GL_TEXTURE_2D, context->last_texture);
+ glDisable(GL_TEXTURE_2D);
+}
+
+void ED_space_clip_free_texture_buffer(SpaceClip *sc)
+{
+ SpaceClipDrawContext *context = sc->draw_context;
+
+ if (context) {
+ glDeleteTextures(1, &context->texture);
+
+ MEM_freeN(context);
+ }
+}
+
+int ED_space_clip_show_trackedit(SpaceClip *sc)
+{
+ if (sc) {
+ return ELEM3(sc->mode, SC_MODE_TRACKING, SC_MODE_RECONSTRUCTION, SC_MODE_DISTORTION);
+ }
+
+ return FALSE;
+}