diff options
author | Ton Roosendaal <ton@blender.org> | 2009-02-14 21:31:19 +0300 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2009-02-14 21:31:19 +0300 |
commit | aba3c36e33cca600a98588d1a9f559922d1aaaed (patch) | |
tree | 7cbfe1ccbef314d93a819ebeec13c30a057365b7 /source | |
parent | 7dce015c907b893b7338995f49bfd563127169a1 (diff) |
2.5
Test: making screencast movies inside Blender!
Hotkey: CTRL+F3. Stop with ESC
Keep in mind it's unfinished :)
Just nice to see how simple cleaner code with the new event
system and job manager can be put to work!
- it uses currently output directory and image/movie
settings from scene. No buttons for this yet.
- Framerate is hardcoded 10 fps
- Thread job takes care of open/write/close movie
or save image files.
- For speed it uses glReadPixels from backbuffer. Have
to consult Brecht for nifty triple buffer trick.
- On file reads it stops now.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/editors/screen/screen_intern.h | 1 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_ops.c | 13 | ||||
-rw-r--r-- | source/blender/editors/screen/screendump.c | 111 |
3 files changed, 109 insertions, 16 deletions
diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h index 8f2e458b296..f39ca7d4c3e 100644 --- a/source/blender/editors/screen/screen_intern.h +++ b/source/blender/editors/screen/screen_intern.h @@ -59,6 +59,7 @@ void ed_screen_context(const bContext *C, bContextDataMember member, bContextDat /* screendump.c */ void SCREEN_OT_screenshot(struct wmOperatorType *ot); +void SCREEN_OT_screencast(struct wmOperatorType *ot); #endif /* ED_SCREEN_INTERN_H */ diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index eabc3bc7993..e973e776c21 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -2038,15 +2038,16 @@ static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *renrec return; /* xmin here is first subrect x coord, xmax defines subrect width */ - xmin = renrect->xmin; - xmax = renrect->xmax - xmin; + xmin = renrect->xmin + rr->crop; + xmax = renrect->xmax - xmin - rr->crop; if (xmax<2) return; - ymin= renrect->ymin; - ymax= renrect->ymax - ymin; + ymin= renrect->ymin + rr->crop; + ymax= renrect->ymax - ymin - rr->crop; if(ymax<2) return; renrect->ymin= renrect->ymax; + } else { xmin = ymin = rr->crop; @@ -2087,7 +2088,7 @@ static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *renrec float *rf= rectf; char *rc= rectc; - /* crop offset */ + /* XXX temp. because crop offset */ if( rectc >= (char *)(ibuf->rect)) { for(x1= 0; x1<xmax; x1++, rf += 4, rc+=4) { rc[0]= FTOCHAR(rf[0]); @@ -2267,6 +2268,7 @@ void ED_operatortypes_screen(void) WM_operatortype_append(SCREEN_OT_screen_set); WM_operatortype_append(SCREEN_OT_screen_full_area); WM_operatortype_append(SCREEN_OT_screenshot); + WM_operatortype_append(SCREEN_OT_screencast); /*frame changes*/ WM_operatortype_append(SCREEN_OT_frame_offset); @@ -2303,6 +2305,7 @@ void ED_keymap_screen(wmWindowManager *wm) WM_keymap_add_item(keymap, "SCREEN_OT_screen_full_area", DOWNARROWKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "SCREEN_OT_screen_full_area", SPACEKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "SCREEN_OT_screenshot", F3KEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "SCREEN_OT_screencast", F3KEY, KM_PRESS, KM_ALT, 0); /* tests */ WM_keymap_add_item(keymap, "SCREEN_OT_region_split", SKEY, KM_PRESS, KM_CTRL|KM_ALT, 0); diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c index 84fe0f87131..9818e2fdd6f 100644 --- a/source/blender/editors/screen/screendump.c +++ b/source/blender/editors/screen/screendump.c @@ -43,6 +43,7 @@ #include "BKE_global.h" #include "BKE_image.h" #include "BKE_utildefines.h" +#include "BKE_writeavi.h" #include "BIF_gl.h" @@ -52,8 +53,13 @@ #include "WM_types.h" #include "WM_api.h" +#include "PIL_time.h" + #include "ED_fileselect.h" #include "ED_screen.h" +#include "ED_screen_types.h" + +#include "screen_intern.h" typedef struct ScreenshotData { unsigned int *dumprect; @@ -177,10 +183,11 @@ void SCREEN_OT_screenshot(wmOperatorType *ot) } /* *************** screenshot movie job ************************* */ -#if 0 + typedef struct ScreenshotJob { + Scene *scene; unsigned int *dumprect; - int dumpsx, dumpsy; + int x, y, dumpsx, dumpsy; short *stop; short *do_update; } ScreenshotJob; @@ -190,6 +197,9 @@ static void screenshot_freejob(void *sjv) { ScreenshotJob *sj= sjv; + if(sj->dumprect) + MEM_freeN(sj->dumprect); + MEM_freeN(sj); } @@ -198,7 +208,15 @@ static void screenshot_freejob(void *sjv) static void screenshot_updatejob(void *sjv) { ScreenshotJob *sj= sjv; + unsigned int *dumprect; + if(sj->dumprect==NULL) { + dumprect= MEM_mallocN(sizeof(int) * sj->dumpsx * sj->dumpsy, "dumprect"); + glReadPixels(sj->x, sj->y, sj->dumpsx, sj->dumpsy, GL_RGBA, GL_UNSIGNED_BYTE, dumprect); + glFinish(); + + sj->dumprect= dumprect; + } } @@ -206,38 +224,110 @@ static void screenshot_updatejob(void *sjv) static void screenshot_startjob(void *sjv, short *stop, short *do_update) { ScreenshotJob *sj= sjv; + RenderData rd= sj->scene->r; + bMovieHandle *mh= BKE_get_movie_handle(sj->scene->r.imtype); + int cfra= 1; + + /* we need this as local variables for renderdata */ + rd.frs_sec= 10; + rd.frs_sec_base= 1.0f; + + if(BKE_imtype_is_movie(rd.imtype)) + mh->start_movie(&rd, sj->dumpsx, sj->dumpsy); + else + mh= NULL; sj->stop= stop; sj->do_update= do_update; + *do_update= 1; // wait for opengl rect + + while(*stop==0 && G.afbreek==0) { + + if(sj->dumprect) { + + if(mh) { + mh->append_movie(&rd, cfra, sj->dumprect, sj->dumpsx, sj->dumpsy); + printf("Append frame %d\n", cfra); + } + else { + ImBuf *ibuf= IMB_allocImBuf(sj->dumpsx, sj->dumpsy, rd.planes, 0, 0); + char name[FILE_MAXDIR+FILE_MAXFILE]; + int ok; + + BKE_makepicstring(sj->scene, name, rd.pic, cfra, rd.imtype); + + ibuf->rect= sj->dumprect; + ok= BKE_write_ibuf(sj->scene, ibuf, name, rd.imtype, rd.subimtype, rd.quality); + + if(ok==0) { + printf("Write error: cannot save %s\n", name); + break; + } + else printf("Saved: %s\n", name); + + /* imbuf knows which rects are not part of ibuf */ + IMB_freeImBuf(ibuf); + } + + MEM_freeN(sj->dumprect); + sj->dumprect= NULL; + + *do_update= 1; + + cfra++; + } + else + PIL_sleep_ms(50); + } + if(mh) + mh->end_movie(); + printf("screencast job stopped\n"); } -static int screenshot_job_invoke(const bContext *C, wmOperator *op, wmEvent *event) +static int screencast_exec(bContext *C, wmOperator *op) { bScreen *screen= CTX_wm_screen(C); wmJob *steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), screen); ScreenshotJob *sj= MEM_callocN(sizeof(ScreenshotJob), "screenshot job"); - /* customdata for preview thread */ + /* setup sj */ + if(RNA_boolean_get(op->ptr, "full")) { + wmWindow *win= CTX_wm_window(C); + sj->x= 0; + sj->y= 0; + sj->dumpsx= win->sizex; + sj->dumpsy= win->sizey; + } + else { + ScrArea *curarea= CTX_wm_area(C); + sj->x= curarea->totrct.xmin; + sj->y= curarea->totrct.ymin; + sj->dumpsx= curarea->totrct.xmax - sj->x; + sj->dumpsy= curarea->totrct.ymax - sj->y; + } sj->scene= CTX_data_scene(C); - + /* setup job */ WM_jobs_customdata(steve, sj, screenshot_freejob); WM_jobs_timer(steve, 0.1, 0, 0); WM_jobs_callbacks(steve, screenshot_startjob, NULL, screenshot_updatejob); + G.afbreek= 0; // XXX? + WM_jobs_start(steve); + return OPERATOR_FINISHED; } -void SCREEN_OT_screenshot_movie(wmOperatorType *ot) +void SCREEN_OT_screencast(wmOperatorType *ot) { - ot->name= "Make Screenshot"; - ot->idname= "SCREEN_OT_screenshot_movie"; + ot->name= "Make Screencast"; + ot->idname= "SCREEN_OT_screencast"; - ot->invoke= screenshot_invoke; - ot->exec= screenshot_exec; + ot->invoke= WM_operator_confirm; + ot->exec= screencast_exec; ot->poll= WM_operator_winactive; ot->flag= 0; @@ -247,5 +337,4 @@ void SCREEN_OT_screenshot_movie(wmOperatorType *ot) } -#endif |