diff options
author | Ton Roosendaal <ton@blender.org> | 2013-03-09 18:57:06 +0400 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2013-03-09 18:57:06 +0400 |
commit | 85f15bb0ed1ee74a86c7877877fc99579bd5605c (patch) | |
tree | 6232f9e2d645c00369d51615df357a9e942846d2 /source/blender/windowmanager/intern/wm_playanim.c | |
parent | c56b39c0e46d384259b9b7670fbc5823399388d6 (diff) |
Blender Anim player fixes:
- RGBA images (without alpha) now don't draw with alpha blending enabled
- Checkerboard backdrop for alpha images now shows on size of image
- Window always clears now, in very dark grey (so you can see black)
- On resizing window, the aspect of image is being kept, keeping the
image always visible within the window frame
- Image now centers OK.
- On pause, playback now halts (it was drawing same image all the time)
Diffstat (limited to 'source/blender/windowmanager/intern/wm_playanim.c')
-rw-r--r-- | source/blender/windowmanager/intern/wm_playanim.c | 116 |
1 files changed, 70 insertions, 46 deletions
diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c index cc364c2a838..a289d182f1c 100644 --- a/source/blender/windowmanager/intern/wm_playanim.c +++ b/source/blender/windowmanager/intern/wm_playanim.c @@ -76,10 +76,16 @@ #include "WM_api.h" /* only for WM_main_playanim */ struct PlayState; -static void playanim_window_zoom(const struct PlayState *ps, const float zoom_offset); +static void playanim_window_zoom(struct PlayState *ps, const float zoom_offset); typedef struct PlayState { + /* window and viewport size */ + int win_x, win_y; + + /* current zoom level */ + float zoom; + /* playback state */ short direction; short next_frame; @@ -207,7 +213,6 @@ typedef struct PlayAnimPict { static struct ListBase picsbase = {NULL, NULL}; static int fromdisk = FALSE; -static float zoomx = 1.0, zoomy = 1.0; static double ptottime = 0.0, swaptime = 0.04; static PlayAnimPict *playanim_step(PlayAnimPict *playanim, int step) @@ -237,8 +242,9 @@ static int pupdate_time(void) return (ptottime < 0); } -static void playanim_toscreen(PlayAnimPict *picture, struct ImBuf *ibuf, int fontid, int fstep) +static void playanim_toscreen(PlayState *ps, PlayAnimPict *picture, struct ImBuf *ibuf, int fontid, int fstep) { + float offsx, offsy; if (ibuf == NULL) { printf("%s: no ibuf for picture '%s'\n", __func__, picture ? picture->name : "<NIL>"); @@ -253,17 +259,29 @@ static void playanim_toscreen(PlayAnimPict *picture, struct ImBuf *ibuf, int fon GHOST_ActivateWindowDrawingContext(g_WS.ghost_window); - glRasterPos2f(0.0f, 0.0f); + /* offset within window */ + offsx = 0.5f * (((float)ps->win_x - ps->zoom * ibuf->x) / (float)ps->win_x); + offsy = 0.5f * (((float)ps->win_y - ps->zoom * ibuf->y) / (float)ps->win_y); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + CLAMP(offsx, 0.0f, 1.0f); + CLAMP(offsy, 0.0f, 1.0f); + glRasterPos2f(offsx, offsy); - fdrawcheckerboard(0.0f, 0.0f, ibuf->x, ibuf->y); + glClearColor(0.1, 0.1, 0.1, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + /* checkerboard for case alpha */ + if (ibuf->planes == 32) { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + fdrawcheckerboard(offsx, offsy, offsx + (ps->zoom * ibuf->x) / (float)ps->win_x, offsy + (ps->zoom * ibuf->y) / (float)ps->win_y); + } + glDrawPixels(ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); glDisable(GL_BLEND); - + pupdate_time(); if (picture && (g_WS.qual & (WS_QUAL_SHIFT | WS_QUAL_LMOUSE)) && (fontid != -1)) { @@ -286,7 +304,7 @@ static void playanim_toscreen(PlayAnimPict *picture, struct ImBuf *ibuf, int fon GHOST_SwapWindowBuffers(g_WS.ghost_window); } -static void build_pict_list(char *first, int totframes, int fstep, int fontid) +static void build_pict_list(PlayState *ps, char *first, int totframes, int fstep, int fontid) { char *mem, filepath[FILE_MAX]; // short val; @@ -302,7 +320,7 @@ static void build_pict_list(char *first, int totframes, int fstep, int fontid) int pic; ibuf = IMB_anim_absolute(anim, 0, IMB_TC_NONE, IMB_PROXY_NONE); if (ibuf) { - playanim_toscreen(NULL, ibuf, fontid, fstep); + playanim_toscreen(ps, NULL, ibuf, fontid, fstep); IMB_freeImBuf(ibuf); } @@ -405,7 +423,7 @@ static void build_pict_list(char *first, int totframes, int fstep, int fontid) ibuf = IMB_loadiffname(picture->name, picture->IB_flags, NULL); } if (ibuf) { - playanim_toscreen(picture, ibuf, fontid, fstep); + playanim_toscreen(ps, picture, ibuf, fontid, fstep); IMB_freeImBuf(ibuf); } pupdate_time(); @@ -709,28 +727,33 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void) case GHOST_kEventWindowSize: case GHOST_kEventWindowMove: { - int sizex, sizey; - - playanim_window_get_size(&sizex, &sizey); + float zoomx, zoomy; + + playanim_window_get_size(&ps->win_x, &ps->win_y); GHOST_ActivateWindowDrawingContext(g_WS.ghost_window); - glViewport(0, 0, sizex, sizey); - glScissor(0, 0, sizex, sizey); - - zoomx = (float) sizex / ps->ibufx; - zoomy = (float) sizey / ps->ibufy; - zoomx = floor(zoomx + 0.5f); - zoomy = floor(zoomy + 0.5f); - if (zoomx < 1.0f) zoomx = 1.0f; - if (zoomy < 1.0f) zoomy = 1.0f; - - sizex = zoomx * ps->ibufx; - sizey = zoomy * ps->ibufy; + zoomx = (float) ps->win_x / ps->ibufx; + zoomy = (float) ps->win_y / ps->ibufy; + + /* zoom always show entire image */ + ps->zoom = MIN2(zoomx, zoomy); + + /* zoom steps of 2 for speed */ + ps->zoom = floor(ps->zoom + 0.5f); + if (ps->zoom < 1.0f) ps->zoom = 1.0f; + + glViewport(0, 0, ps->win_x, ps->win_y); + glScissor(0, 0, ps->win_x, ps->win_y); + + /* unified matrix, note it affects offset for drawing */ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f); + glMatrixMode(GL_MODELVIEW); - glPixelZoom(zoomx, zoomy); - glEnable(GL_DITHER); + glPixelZoom(ps->zoom, ps->zoom); ptottime = 0.0; - playanim_toscreen(ps->picture, ps->curframe_ibuf, ps->fontid, ps->fstep); + playanim_toscreen(ps, ps->picture, ps->curframe_ibuf, ps->fontid, ps->fstep); break; } @@ -787,20 +810,19 @@ static void playanim_window_open(const char *title, int posx, int posy, int size FALSE /* no stereo */, FALSE); } -static void playanim_window_zoom(const PlayState *ps, const float zoom_offset) +static void playanim_window_zoom(PlayState *ps, const float zoom_offset) { int sizex, sizey; /* int ofsx, ofsy; */ /* UNUSED */ - if (zoomx + zoom_offset > 0.0f) zoomx += zoom_offset; - if (zoomy + zoom_offset > 0.0f) zoomy += zoom_offset; + if (ps->zoom + zoom_offset > 0.0f) ps->zoom += zoom_offset; // playanim_window_get_position(&ofsx, &ofsy); playanim_window_get_size(&sizex, &sizey); /* ofsx += sizex / 2; */ /* UNUSED */ /* ofsy += sizey / 2; */ /* UNUSED */ - sizex = zoomx * ps->ibufx; - sizey = zoomy * ps->ibufy; + sizex = ps->zoom * ps->ibufx; + sizey = ps->zoom * ps->ibufy; /* ofsx -= sizex / 2; */ /* UNUSED */ /* ofsy -= sizey / 2; */ /* UNUSED */ // window_set_position(g_WS.ghost_window,sizex,sizey); @@ -836,6 +858,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv) ps.stopped = FALSE; ps.picture = NULL; ps.dropped_file[0] = 0; + ps.zoom = 1.0f; /* resetmap = FALSE */ ps.fstep = 1; @@ -941,20 +964,16 @@ static char *wm_main_playanim_intern(int argc, const char **argv) #endif #endif //XXX25 - /* XXX, fixme zr */ { -// extern void add_to_mainqueue(wmWindow *win, void *user_data, short evt, short val, char ascii); GHOST_EventConsumerHandle consumer = GHOST_CreateEventConsumer(ghost_event_proc, &ps); g_WS.ghost_system = GHOST_CreateSystem(); GHOST_AddEventConsumer(g_WS.ghost_system, consumer); - - playanim_window_open("Blender:Anim", start_x, start_y, ibuf->x, ibuf->y, 0); -//XXX25 window_set_handler(g_WS.ghost_window, add_to_mainqueue, NULL); + /* unified matrix, note it affects offset for drawing */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f); @@ -972,11 +991,15 @@ static char *wm_main_playanim_intern(int argc, const char **argv) ps.ibufx = ibuf->x; ps.ibufy = ibuf->y; + + ps.win_x = ps.ibufx; + ps.win_y = ps.ibufy; if (maxwinx % ibuf->x) maxwinx = ibuf->x * (1 + (maxwinx / ibuf->x)); if (maxwiny % ibuf->y) maxwiny = ibuf->y * (1 + (maxwiny / ibuf->y)); - glClearColor(0.0, 0.0, 0.0, 0.0); + + glClearColor(0.1, 0.1, 0.1, 0.0); glClear(GL_COLOR_BUFFER_BIT); GHOST_SwapWindowBuffers(g_WS.ghost_window); @@ -987,11 +1010,11 @@ static char *wm_main_playanim_intern(int argc, const char **argv) efra = MAXFRAME; } - build_pict_list(filepath, (efra - sfra) + 1, ps.fstep, ps.fontid); + build_pict_list(&ps, filepath, (efra - sfra) + 1, ps.fstep, ps.fontid); for (i = 2; i < argc; i++) { BLI_strncpy(filepath, argv[i], sizeof(filepath)); - build_pict_list(filepath, (efra - sfra) + 1, ps.fstep, ps.fontid); + build_pict_list(&ps, filepath, (efra - sfra) + 1, ps.fstep, ps.fontid); } IMB_freeImBuf(ibuf); @@ -1064,8 +1087,8 @@ static char *wm_main_playanim_intern(int argc, const char **argv) while (pupdate_time()) PIL_sleep_ms(1); ptottime -= swaptime; - playanim_toscreen(ps.picture, ibuf, ps.fontid, ps.fstep); - } /* else deleten */ + playanim_toscreen(&ps, ps.picture, ibuf, ps.fontid, ps.fstep); + } /* else delete */ else { printf("error: can't play this image type\n"); exit(0); @@ -1083,16 +1106,17 @@ static char *wm_main_playanim_intern(int argc, const char **argv) ps.next_frame = ps.direction; - while ((hasevent = GHOST_ProcessEvents(g_WS.ghost_system, 0) || ps.wait2 != 0)) { + while ( (hasevent = GHOST_ProcessEvents(g_WS.ghost_system, 0)) || ps.wait2 != 0) { if (hasevent) { GHOST_DispatchEvents(g_WS.ghost_system); } + /* Note, this still draws for mousemoves on pause */ if (ps.wait2) { if (hasevent) { if (ibuf) { while (pupdate_time()) PIL_sleep_ms(1); ptottime -= swaptime; - playanim_toscreen(ps.picture, ibuf, ps.fontid, ps.fstep); + playanim_toscreen(&ps, ps.picture, ibuf, ps.fontid, ps.fstep); } } } |