Movie Clip Editor: implemented option to display frame using OpenGL textures
Initial idea was to perform bilinear filtering for displaying proxied frame to make it looking a bit smoother. It was done but it was also discovered that using such kind of texture buffers helps on some crappy videocards when playing $k footage. Currently check for NPOT support is disabled, so use this option with care.
This commit is contained in:
@@ -559,6 +559,8 @@ class CLIP_PT_display(Panel):
|
||||
elif sc.mode == 'RECONSTRUCTION':
|
||||
col.prop(sc, "show_stable", text="Stable")
|
||||
|
||||
col.prop(sc, "use_texture_buffer")
|
||||
|
||||
clip = sc.clip
|
||||
if clip:
|
||||
col.label(text="Display Aspect Ratio:")
|
||||
|
||||
@@ -5273,6 +5273,7 @@ static void lib_link_screen(FileData *fd, Main *main)
|
||||
sclip->clip= newlibadr_us(fd, sc->id.lib, sclip->clip);
|
||||
|
||||
sclip->scopes.track_preview = NULL;
|
||||
sclip->draw_context = NULL;
|
||||
sclip->scopes.ok = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +58,10 @@ void ED_clip_point_undistorted_pos(SpaceClip *sc, float co[2], float nco[2]);
|
||||
void ED_clip_point_stable_pos(struct bContext *C, float x, float y, float *xr, float *yr);
|
||||
void ED_clip_mouse_pos(struct bContext *C, struct wmEvent *event, float co[2]);
|
||||
|
||||
void ED_space_clip_load_movieclip_buffer(struct SpaceClip *sc, struct ImBuf *ibuf);
|
||||
void ED_space_clip_unload_movieclip_buffer(struct SpaceClip *sc);
|
||||
void ED_space_clip_free_texture_buffer(struct SpaceClip *sc);
|
||||
|
||||
/* clip_ops.c */
|
||||
void ED_operatormacros_clip(void);
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ set(INC
|
||||
../../makesdna
|
||||
../../makesrna
|
||||
../../windowmanager
|
||||
../../gpu
|
||||
../../../../intern/guardedalloc
|
||||
${GLEW_INCLUDE_PATH}
|
||||
)
|
||||
|
||||
@@ -4,6 +4,6 @@ Import ('env')
|
||||
sources = env.Glob('*.c')
|
||||
defs = []
|
||||
incs = '../include ../../blenkernel ../../blenloader ../../blenfont ../../blenlib ../../imbuf ../../makesdna'
|
||||
incs += ' ../../makesrna ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
|
||||
incs += ' ../../makesrna ../../windowmanager #/intern/guardedalloc #/extern/glew/include ../../gpu'
|
||||
|
||||
env.BlenderLib ( 'bf_editors_space_clip', sources, Split(incs), defs, libtype=['core'], priority=[95] )
|
||||
|
||||
@@ -216,9 +216,6 @@ static void draw_movieclip_buffer(SpaceClip *sc, ARegion *ar, ImBuf *ibuf,
|
||||
int x, y;
|
||||
MovieClip *clip= ED_space_clip(sc);
|
||||
|
||||
/* set zoom */
|
||||
glPixelZoom(zoomx*width/ibuf->x, zoomy*height/ibuf->y);
|
||||
|
||||
/* find window pixel coordinates of origin */
|
||||
UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x, &y);
|
||||
|
||||
@@ -230,8 +227,36 @@ static void draw_movieclip_buffer(SpaceClip *sc, ARegion *ar, ImBuf *ibuf,
|
||||
IMB_rect_from_float(ibuf);
|
||||
}
|
||||
|
||||
if(ibuf->rect)
|
||||
glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
|
||||
if(ibuf->rect) {
|
||||
if(sc->flag & SC_TEXTURE_BUFFER) {
|
||||
ED_space_clip_load_movieclip_buffer(sc, ibuf);
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(x, y, 0);
|
||||
glScalef(zoomx, zoomy, 1.0f);
|
||||
glMultMatrixf(sc->stabmat);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f);
|
||||
glTexCoord2f(1.0f, 0.0f); glVertex2f(width, 0.0f);
|
||||
glTexCoord2f(1.0f, 1.0f); glVertex2f(width, height);
|
||||
glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, height);
|
||||
glEnd();
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
ED_space_clip_unload_movieclip_buffer(sc);
|
||||
}
|
||||
else {
|
||||
/* set zoom */
|
||||
glPixelZoom(zoomx*width/ibuf->x, zoomy*height/ibuf->y);
|
||||
|
||||
glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
|
||||
|
||||
/* reset zoom */
|
||||
glPixelZoom(1.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* draw boundary border for frame if stabilization is enabled */
|
||||
@@ -260,10 +285,6 @@ static void draw_movieclip_buffer(SpaceClip *sc, ARegion *ar, ImBuf *ibuf,
|
||||
glDisable(GL_COLOR_LOGIC_OP);
|
||||
glDisable(GL_LINE_STIPPLE);
|
||||
}
|
||||
|
||||
|
||||
/* reset zoom */
|
||||
glPixelZoom(1.0f, 1.0f);
|
||||
}
|
||||
|
||||
static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackingTrack *track)
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_movieclip.h"
|
||||
#include "BKE_context.h"
|
||||
@@ -40,6 +42,8 @@
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_math.h"
|
||||
|
||||
#include "GPU_extensions.h"
|
||||
|
||||
#include "IMB_imbuf_types.h"
|
||||
#include "IMB_imbuf.h"
|
||||
|
||||
@@ -47,6 +51,7 @@
|
||||
#include "ED_clip.h"
|
||||
|
||||
#include "BIF_gl.h"
|
||||
#include "BIF_glutil.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
@@ -309,3 +314,145 @@ 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 {
|
||||
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 */
|
||||
} SpaceClipDrawContext;
|
||||
|
||||
void 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;
|
||||
|
||||
if (!context) {
|
||||
context = MEM_callocN(sizeof(SpaceClipDrawContext), "SpaceClipDrawContext");
|
||||
sc->draw_context = context;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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 0
|
||||
/* disabled for now because current tracking users have got NPOT textures
|
||||
* working smoothly on their computers and forcing re-scaling during playback
|
||||
* slows down playback a lot */
|
||||
|
||||
/* if videocard doesn't support NPOT textures, need to do rescaling */
|
||||
if (!GPU_non_power_of_two_support()) {
|
||||
if (!is_power_of_2_i(width) || !is_power_of_2_i(height)) {
|
||||
width = power_of_2_max_i(width);
|
||||
height = power_of_2_max_i(height);
|
||||
|
||||
if (ibuf->x != width || ibuf->y != height) {
|
||||
if (frect) {
|
||||
fscalerect= MEM_mallocN(width*width*sizeof(*fscalerect)*4, "fscalerect");
|
||||
gluScaleImage(GL_RGBA, ibuf->x, ibuf->y, GL_FLOAT, ibuf->rect_float, width, height, GL_FLOAT, fscalerect);
|
||||
|
||||
frect = fscalerect;
|
||||
}
|
||||
else {
|
||||
scalerect= MEM_mallocN(width*height*sizeof(*scalerect), "scalerect");
|
||||
gluScaleImage(GL_RGBA, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, ibuf->rect, width, height, GL_UNSIGNED_BYTE, scalerect);
|
||||
|
||||
rect = scalerect;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,6 +214,8 @@ static void clip_free(SpaceLink *sl)
|
||||
|
||||
if(sc->scopes.track_preview)
|
||||
IMB_freeImBuf(sc->scopes.track_preview);
|
||||
|
||||
ED_space_clip_free_texture_buffer(sc);
|
||||
}
|
||||
|
||||
/* spacetype; init callback */
|
||||
@@ -229,6 +231,7 @@ static SpaceLink *clip_duplicate(SpaceLink *sl)
|
||||
/* clear or remove stuff from old */
|
||||
scn->scopes.track_preview= NULL;
|
||||
scn->scopes.ok= 0;
|
||||
scn->draw_context= NULL;
|
||||
|
||||
return (SpaceLink *)scn;
|
||||
}
|
||||
|
||||
@@ -521,6 +521,8 @@ typedef struct SpaceClip {
|
||||
|
||||
/* movie postprocessing */
|
||||
int postproc_flag, pad2;
|
||||
|
||||
void *draw_context;
|
||||
} SpaceClip;
|
||||
|
||||
/* view3d Now in DNA_view3d_types.h */
|
||||
@@ -902,6 +904,7 @@ enum {
|
||||
#define SC_SHOW_GRAPH_TRACKS (1<<15)
|
||||
/*#define SC_SHOW_PYRAMID_LEVELS (1<<16) */ /* UNUSED */
|
||||
#define SC_LOCK_TIMECURSOR (1<<17)
|
||||
#define SC_TEXTURE_BUFFER (1<<18)
|
||||
|
||||
/* SpaceClip->mode */
|
||||
#define SC_MODE_TRACKING 0
|
||||
|
||||
@@ -2985,6 +2985,11 @@ static void rna_def_space_clip(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Show Tracks", "Display the speed curves (in \"x\" direction red, in \"y\" direction green) for the selected tracks");
|
||||
RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL);
|
||||
|
||||
prop= RNA_def_property(srna, "use_texture_buffer", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Use Texture Buffer", "Use texture buffer to display o,age frames frame on screen");
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_TEXTURE_BUFFER);
|
||||
RNA_def_property_update(prop, NC_WINDOW, NULL);
|
||||
|
||||
/* ** channels ** */
|
||||
|
||||
/* show_red_channel */
|
||||
|
||||
Reference in New Issue
Block a user