diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2010-03-29 02:45:14 +0400 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2010-03-29 02:45:14 +0400 |
commit | f4e9c5d71e7de908384c713da52585e027abe49e (patch) | |
tree | 48e1dab2ae492a1e1aa0d3f7ae191a844b86adf0 /source | |
parent | e2cb63574485efb2a9ccde1f0b15a29d086dd194 (diff) | |
parent | 33ee3fc6fe0d387e1efb2b545cab441867fb1b48 (diff) |
Merged changes in the trunk up to revision 27817.
Diffstat (limited to 'source')
55 files changed, 542 insertions, 393 deletions
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c index 2d79626a3d6..2289cf7fc89 100644 --- a/source/blender/blenfont/intern/blf_font.c +++ b/source/blender/blenfont/intern/blf_font.c @@ -150,8 +150,9 @@ void blf_font_draw(FontBLF *font, char *str) void blf_font_buffer(FontBLF *font, char *str) { - unsigned char *data, *cbuf; + unsigned char *cbuf; unsigned int c; + unsigned char b_col_char[3]; GlyphBLF *g, *g_prev; FT_Vector delta; FT_UInt glyph_index; @@ -159,14 +160,18 @@ void blf_font_buffer(FontBLF *font, char *str) int pen_x, pen_y, y, x, yb, diff; int i, has_kerning, st, chx, chy; - if (!font->glyph_cache) + if (!font->glyph_cache || (!font->b_fbuf && !font->b_cbuf)) return; - + i= 0; pen_x= (int)font->pos[0]; pen_y= (int)font->pos[1]; has_kerning= FT_HAS_KERNING(font->face); g_prev= NULL; + + b_col_char[0]= font->b_col[0] * 255; + b_col_char[1]= font->b_col[1] * 255; + b_col_char[2]= font->b_col[2] * 255; while (str[i]) { c= blf_utf8_next((unsigned char *)str, &i); @@ -216,15 +221,19 @@ void blf_font_buffer(FontBLF *font, char *str) else chy= pen_y + ((int)g->pos_y); - if (font->b_fbuf) { - if (chx >= 0 && chx < font->bw && pen_y >= 0 && pen_y < font->bh) { - if (g->pitch < 0) - yb= 0; - else - yb= g->height-1; + if ((chx + g->width) >= 0 && chx < font->bw && (pen_y + g->height) >= 0 && pen_y < font->bh) { + /* dont draw beyond the buffer bounds */ + int width_clip= g->width; + int height_clip= g->height; - for (y= 0; y < g->height; y++) { - for (x= 0; x < g->width; x++) { + if (width_clip + chx > font->bw) width_clip -= chx + width_clip - font->bw; + if (height_clip + pen_y > font->bh) height_clip -= pen_y + height_clip - font->bh; + + yb= g->pitch < 0 ? 0 : g->height-1; + + if (font->b_fbuf) { + for (y= 0; y < height_clip; y++) { + for (x= 0; x < width_clip; x++) { a= *(g->bitmap + x + (yb * g->pitch)) / 255.0f; @@ -249,22 +258,10 @@ void blf_font_buffer(FontBLF *font, char *str) yb--; } } - } - - if (font->b_cbuf) { - if (chx >= 0 && chx < font->bw && pen_y >= 0 && pen_y < font->bh) { - char b_col_char[3]; - b_col_char[0]= font->b_col[0] * 255; - b_col_char[1]= font->b_col[1] * 255; - b_col_char[2]= font->b_col[2] * 255; - - if (g->pitch < 0) - yb= 0; - else - yb= g->height-1; - for (y= 0; y < g->height; y++) { - for (x= 0; x < g->width; x++) { + if (font->b_cbuf) { + for (y= 0; y < height_clip; y++) { + for (x= 0; x < width_clip; x++) { a= *(g->bitmap + x + (yb * g->pitch)) / 255.0f; if(a > 0.0f) { diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h index df51d017594..915f59be01a 100644 --- a/source/blender/blenkernel/BKE_image.h +++ b/source/blender/blenkernel/BKE_image.h @@ -141,6 +141,9 @@ struct RenderPass *BKE_image_multilayer_index(struct RenderResult *rr, struct Im /* for multilayer images as well as for render-viewer */ struct RenderResult *BKE_image_acquire_renderresult(struct Scene *scene, struct Image *ima); void BKE_image_release_renderresult(struct Scene *scene, struct Image *ima); + +/* for multiple slot render, call this before render */ +void BKE_image_backup_render(struct Scene *scene, struct Image *ima); /* goes over all textures that use images */ void BKE_image_free_all_textures(void); diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index c85bd2f90b3..ffd504f5945 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -1408,7 +1408,7 @@ ListBase *get_collider_cache(Scene *scene, Object *self, Group *group) } else { for(base = scene->base.first; base; base = base->next) - if(self && (base->lay & self->lay)==0) + if(!self || (base->lay & self->lay)) add_collider_cache_object(&objs, base->object, self, 0); } diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 3e28dcc7acd..487ecb810d4 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -295,9 +295,9 @@ static Render *fastshade_get_render(Scene *scene) /* XXX ugly global still, but we can't do preview while rendering */ if(G.rendering==0) { - Render *re= RE_GetRender("_Shade View_", RE_SLOT_DEFAULT); + Render *re= RE_GetRender("_Shade View_"); if(re==NULL) { - re= RE_NewRender("_Shade View_", RE_SLOT_DEFAULT); + re= RE_NewRender("_Shade View_"); RE_Database_Baking(re, scene, 0, 0); /* 0= no faces */ } @@ -311,7 +311,7 @@ static Render *fastshade_get_render(Scene *scene) /* called on file reading */ void fastshade_free_render(void) { - Render *re= RE_GetRender("_Shade View_", RE_SLOT_DEFAULT); + Render *re= RE_GetRender("_Shade View_"); if(re) { RE_Database_Free(re); diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 1a3c53e293f..2d582157233 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -229,7 +229,7 @@ static void image_free_buffers(Image *ima) if(ima->anim) IMB_free_anim(ima->anim); ima->anim= NULL; - + if(ima->rr) { RE_FreeRenderResult(ima->rr); ima->rr= NULL; @@ -243,6 +243,8 @@ static void image_free_buffers(Image *ima) /* called by library too, do not free ima itself */ void free_image(Image *ima) { + int a; + image_free_buffers(ima); if (ima->packedfile) { freePackedFile(ima->packedfile); @@ -253,9 +255,11 @@ void free_image(Image *ima) if (ima->preview) { BKE_previewimg_free(&ima->preview); } - if (ima->render_text) { - MEM_freeN(ima->render_text); - ima->render_text= NULL; + for(a=0; a<IMA_MAX_RENDER_SLOT; a++) { + if(ima->renders[a]) { + RE_FreeRenderResult(ima->renders[a]); + ima->renders[a]= NULL; + } } } @@ -1005,7 +1009,7 @@ static void stampdata(Scene *scene, StampData *stamp_data, int do_prefix) } { - Render *re= RE_GetRender(scene->id.name, RE_SLOT_RENDERING); + Render *re= RE_GetRender(scene->id.name); RenderStats *stats= re ? RE_GetStats(re):NULL; if (stats && (scene->r.stamp & R_STAMP_RENDERTIME)) { @@ -1511,20 +1515,48 @@ RenderPass *BKE_image_multilayer_index(RenderResult *rr, ImageUser *iuser) return rpass; } -RenderResult *BKE_image_acquire_renderresult(struct Scene *scene, Image *ima) +RenderResult *BKE_image_acquire_renderresult(Scene *scene, Image *ima) { - if(ima->rr) + if(ima->rr) { return ima->rr; - else if(ima->type==IMA_TYPE_R_RESULT) - return RE_AcquireResultRead(RE_GetRender(scene->id.name, RE_SLOT_VIEW)); - return NULL; + } + else if(ima->type==IMA_TYPE_R_RESULT) { + if(ima->render_slot == ima->last_render_slot) + return RE_AcquireResultRead(RE_GetRender(scene->id.name)); + else + return ima->renders[ima->render_slot]; + } + else + return NULL; } -void BKE_image_release_renderresult(struct Scene *scene, Image *ima) +void BKE_image_release_renderresult(Scene *scene, Image *ima) { if(ima->rr); - else if(ima->type==IMA_TYPE_R_RESULT) - RE_ReleaseResult(RE_GetRender(scene->id.name, RE_SLOT_VIEW)); + else if(ima->type==IMA_TYPE_R_RESULT) { + if(ima->render_slot == ima->last_render_slot) + RE_ReleaseResult(RE_GetRender(scene->id.name)); + } +} + +void BKE_image_backup_render(Scene *scene, Image *ima) +{ + /* called right before rendering, ima->renders contains render + result pointers for everything but the current render */ + Render *re= RE_GetRender(scene->id.name); + int slot= ima->render_slot, last= ima->last_render_slot; + + if(slot != last) { + if(ima->renders[slot]) { + RE_FreeRenderResult(ima->renders[slot]); + ima->renders[slot]= NULL; + } + + ima->renders[last]= NULL; + RE_SwapResult(re, &ima->renders[last]); + } + + ima->last_render_slot= slot; } /* after imbuf load, openexr type can return with a exrhandle open */ @@ -1839,6 +1871,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_ float dither; int channels, layer, pass; ImBuf *ibuf; + int from_render= (ima->render_slot == ima->last_render_slot); if(!(iuser && iuser->scene)) return NULL; @@ -1847,14 +1880,29 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_ if(!lock_r) return NULL; - re= RE_GetRender(iuser->scene->id.name, RE_SLOT_VIEW); + re= RE_GetRender(iuser->scene->id.name); channels= 4; layer= (iuser)? iuser->layer: 0; pass= (iuser)? iuser->pass: 0; + + if(from_render) + RE_AcquireResultImage(re, &rres); + else if(ima->renders[ima->render_slot]) + rres= *(ima->renders[ima->render_slot]); + else + memset(&rres, 0, sizeof(RenderResult)); + if(!(rres.rectx > 0 && rres.recty > 0)) { + RE_ReleaseResultImage(re); + return NULL; + } + + /* release is done in BKE_image_release_ibuf using lock_r */ + if(from_render) + *lock_r= re; + /* this gives active layer, composite or seqence result */ - RE_AcquireResultImage(re, &rres); rect= (unsigned int *)rres.rect32; rectf= rres.rectf; rectz= rres.rectz; @@ -1885,11 +1933,6 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_ rectz= rpass->rect; } } - - if(!(rectf || rect)) { - RE_ReleaseResultImage(re); - return NULL; - } ibuf= image_get_ibuf(ima, IMA_NO_INDEX, 0); @@ -1898,11 +1941,18 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_ ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, 0, 0); image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0); } + + if(!(rectf || rect)) + return ibuf; + ibuf->x= rres.rectx; ibuf->y= rres.recty; - if(ibuf->rect_float!=rectf || rect) /* ensure correct redraw */ + if(ibuf->rect_float!=rectf || rect) { /* ensure correct redraw */ + BLI_lock_thread(LOCK_CUSTOM1); imb_freerectImBuf(ibuf); + BLI_unlock_thread(LOCK_CUSTOM1); + } if(rect) ibuf->rect= rect; @@ -1915,9 +1965,6 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_ ima->ok= IMA_OK_LOADED; - /* release is done in BKE_image_release_ibuf using lock_r */ - *lock_r= re; - return ibuf; } diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 5cda09cad85..96877a9ae9e 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -3717,9 +3717,10 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd, /* calculate projection matrix */ invert_m4_m4(projectors[i].projmat, projectors[i].ob->obmat); + projectors[i].uci= NULL; + if(projectors[i].ob->type == OB_CAMERA) { cam = (Camera *)projectors[i].ob->data; - projectors[i].uci= NULL; if(cam->flag & CAM_PANORAMA) { projectors[i].uci= project_camera_info(projectors[i].ob, NULL, aspx, aspy); diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 17f6bd10859..913ec3d4cae 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -2175,9 +2175,9 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int RenderResult rres; if(rendering) - re= RE_NewRender(" do_build_seq_ibuf", RE_SLOT_DEFAULT); + re= RE_NewRender(" do_build_seq_ibuf"); else - re= RE_NewRender(sce->id.name, RE_SLOT_VIEW); + re= RE_NewRender(sce->id.name); RE_BlenderFrame(re, sce, NULL, sce->lay, frame); diff --git a/source/blender/blenkernel/intern/writeframeserver.c b/source/blender/blenkernel/intern/writeframeserver.c index cf3a36419b4..a7b6bcf3a09 100644 --- a/source/blender/blenkernel/intern/writeframeserver.c +++ b/source/blender/blenkernel/intern/writeframeserver.c @@ -1,4 +1,6 @@ /* + * $Id$ + * * Frameserver * Makes Blender accessible from TMPGenc directly using VFAPI (you can * use firefox too ;-) @@ -93,7 +95,7 @@ static int select_was_interrupted_by_signal() return (errno == EINTR); } -static int closesocket(int fd) +static int closesocket(int fd) { return close(fd); } @@ -140,10 +142,10 @@ int start_frameserver(struct Scene *scene, RenderData *rd, int rectx, int recty, return 1; } -static char index_page[] -= -"HTTP/1.1 200 OK\n" -"Content-Type: text/html\n\n" +static char index_page[] = +"HTTP/1.1 200 OK\r\n" +"Content-Type: text/html\r\n" +"\r\n" "<html><head><title>Blender Frameserver</title></head>\n" "<body><pre>\n" "<H2>Blender Frameserver</H2>\n" @@ -156,9 +158,10 @@ static char index_page[] "\n" "</pre></body></html>\n"; -static char good_bye[] -= "HTTP/1.1 200 OK\n" -"Content-Type: text/html\n\n" +static char good_bye[] = +"HTTP/1.1 200 OK\r\n" +"Content-Type: text/html\r\n" +"\r\n" "<html><head><title>Blender Frameserver</title></head>\n" "<body><pre>\n" "Render stopped. Goodbye</pre></body></html>"; @@ -216,13 +219,14 @@ static int handle_request(RenderData *rd, char * req) if (strcmp(path, "/info.txt") == 0) { char buf[4096]; - sprintf(buf, - "HTTP/1.1 200 OK\n" - "Content-Type: text/html\n\n" + sprintf(buf, + "HTTP/1.1 200 OK\r\n" + "Content-Type: text/html\r\n" + "\r\n" "start %d\n" "end %d\n" "width %d\n" - "height %d\n" + "height %d\n" "rate %d\n" "ratescale %d\n", rd->sfra, @@ -317,10 +321,11 @@ static void serve_ppm(int *pixels, int rectx, int recty) int y; char header[1024]; - sprintf(header, - "HTTP/1.1 200 OK\n" - "Content-Type: image/ppm\n" - "Connection: close\n\n" + sprintf(header, + "HTTP/1.1 200 OK\r\n" + "Content-Type: image/ppm\r\n" + "Connection: close\r\n" + "\r\n" "P6\n" "# Creator: blender frameserver v0.0.1\n" "%d %d\n" @@ -343,7 +348,7 @@ static void serve_ppm(int *pixels, int rectx, int recty) target += 3; src += 4; } - safe_write((char*)row, 3 * rectx); + safe_write((char*)row, 3 * rectx); } free(row); closesocket(connsock); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 350f779e490..5aeaf679bb0 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -1183,6 +1183,7 @@ void blo_make_image_pointer_map(FileData *fd, Main *oldmain) { Image *ima= oldmain->image.first; Scene *sce= oldmain->scene.first; + int a; fd->imamap= oldnewmap_new(); @@ -1192,6 +1193,9 @@ void blo_make_image_pointer_map(FileData *fd, Main *oldmain) oldnewmap_insert(fd->imamap, ibuf, ibuf, 0); if(ima->gputexture) oldnewmap_insert(fd->imamap, ima->gputexture, ima->gputexture, 0); + for(a=0; a<IMA_MAX_RENDER_SLOT; a++) + if(ima->renders[a]) + oldnewmap_insert(fd->imamap, ima->renders[a], ima->renders[a], 0); } for(; sce; sce= sce->id.next) { if(sce->nodetree) { @@ -1209,7 +1213,7 @@ void blo_end_image_pointer_map(FileData *fd, Main *oldmain) OldNew *entry= fd->imamap->entries; Image *ima= oldmain->image.first; Scene *sce= oldmain->scene.first; - int i; + int i, a; /* used entries were restored, so we put them to zero */ for (i=0; i<fd->imamap->nentries; i++, entry++) { @@ -1231,6 +1235,8 @@ void blo_end_image_pointer_map(FileData *fd, Main *oldmain) } ima->gputexture= newimaadr(fd, ima->gputexture); + for(a=0; a<IMA_MAX_RENDER_SLOT; a++) + ima->renders[a]= newimaadr(fd, ima->renders[a]); } for(; sce; sce= sce->id.next) { if(sce->nodetree) { @@ -2653,7 +2659,8 @@ static void direct_link_image(FileData *fd, Image *ima) ima->anim= NULL; ima->rr= NULL; ima->repbind= NULL; - ima->render_text= newdataadr(fd, ima->render_text); + memset(ima->renders, 0, sizeof(ima->renders)); + ima->last_render_slot= ima->render_slot; ima->packedfile = direct_link_packedfile(fd, ima->packedfile); ima->preview = direct_link_preview_image(fd, ima->preview); diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index dcbfa7852f6..856f1d71c6d 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -1625,10 +1625,6 @@ static void write_images(WriteData *wd, ListBase *idbase) } write_previews(wd, ima->preview); - - /* exception: render text only saved in undo files (wd->current) */ - if (ima->render_text && wd->current) - writedata(wd, DATA, IMA_RW_MAXTEXT, ima->render_text); } ima= ima->id.next; } diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 842b66a1f6f..7f90575acc0 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -153,6 +153,7 @@ struct RegionView3D *ED_view3d_context_rv3d(struct bContext *C); void ED_view3d_init_mats_rv3d(struct Object *ob, struct RegionView3D *rv3d); +void ED_view3d_scene_layers_copy(struct View3D *v3d, struct Scene *scene); void ED_view3d_scene_layers_update(struct Main *bmain, struct Scene *scene); int ED_view3d_scene_layer_set(int lay, const int *values); diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 2a20c86744d..734602d5b32 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -6757,8 +6757,8 @@ void MESH_OT_subdivide(wmOperatorType *ot) /* properties */ RNA_def_int(ot->srna, "number_cuts", 1, 1, INT_MAX, "Number of Cuts", "", 1, 10); - RNA_def_float(ot->srna, "fractal", 0.0, 0.0f, FLT_MAX, "Fractal", "Fractal randomness factor.", 0.0f, 1000.0f); RNA_def_float(ot->srna, "smoothness", 0.0f, 0.0f, FLT_MAX, "Smoothness", "Smoothness factor.", 0.0f, 1000.0f); + RNA_def_float(ot->srna, "fractal", 0.0, 0.0f, FLT_MAX, "Fractal", "Fractal randomness factor.", 0.0f, 1000.0f); } /********************** Fill Operators *************************/ diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index a2070771844..fd2509cbfda 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -1709,13 +1709,17 @@ Base *ED_object_add_duplicate(Scene *scene, Base *base, int dupflag) clear_id_newpoins(); clear_sca_new_poins(); /* sensor/contr/act */ - + basen= object_add_duplicate_internal(scene, base, dupflag); + if (basen == NULL) { + return NULL; + } + ob= basen->object; - + DAG_scene_sort(scene); ED_render_id_flush_update(G.main, ob->data); - + return basen; } @@ -1736,6 +1740,10 @@ static int duplicate_exec(bContext *C, wmOperator *op) the list is made in advance */ ED_base_object_select(base, BA_DESELECT); + if (basen == NULL) { + continue; + } + /* new object becomes active */ if(BASACT==base) ED_base_object_activate(C, basen); @@ -1798,36 +1806,42 @@ static int add_named_exec(bContext *C, wmOperator *op) int linked= RNA_boolean_get(op->ptr, "linked"); int dupflag= (linked)? 0: U.dupflag; char name[32]; - + /* find object, create fake base */ RNA_string_get(op->ptr, "name", name); ob= (Object *)find_id("OB", name); if(ob==NULL) return OPERATOR_CANCELLED; - + base= MEM_callocN(sizeof(Base), "duplibase"); base->object= ob; base->flag= ob->flag; - + /* prepare dupli */ clear_id_newpoins(); clear_sca_new_poins(); /* sensor/contr/act */ - + basen= object_add_duplicate_internal(scene, base, dupflag); + + if (basen == NULL) { + MEM_freeN(base); + return OPERATOR_CANCELLED; + } + basen->lay= basen->object->lay= scene->lay; - + ED_object_location_from_view(C, basen->object->loc); ED_base_object_activate(C, basen); - + copy_object_set_idnew(C, dupflag); - + DAG_scene_sort(scene); DAG_ids_flush_update(0); - + MEM_freeN(base); - + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); - + return OPERATOR_FINISHED; } diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index 8d5268bcb79..d3f9847d9b9 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -140,7 +140,7 @@ static void init_bake_internal(BakeRender *bkr, bContext *C) bkr->sa= biggest_image_area(CTX_wm_screen(C)); /* can be NULL */ bkr->scene= scene; bkr->actob= (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT : NULL; - bkr->re= RE_NewRender("_Bake View_", RE_SLOT_DEFAULT); + bkr->re= RE_NewRender("_Bake View_"); if(scene->r.bake_mode==RE_BAKE_AO) { /* If raytracing or AO is disabled, switch it on temporarily for baking. */ diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index 678de91e1b4..dcafbc5b252 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -30,30 +30,24 @@ #include "MEM_guardedalloc.h" -#include "BLI_math.h" #include "BLI_blenlib.h" -#include "BLI_editVert.h" -#include "BLI_dlrbTree.h" +#include "BLI_math.h" +#include "BLI_threads.h" #include "DNA_scene_types.h" #include "BKE_blender.h" #include "BKE_colortools.h" #include "BKE_context.h" -#include "BKE_customdata.h" #include "BKE_global.h" #include "BKE_image.h" -#include "BKE_idprop.h" #include "BKE_library.h" #include "BKE_main.h" -#include "BKE_mesh.h" #include "BKE_multires.h" #include "BKE_report.h" #include "BKE_scene.h" #include "BKE_screen.h" #include "BKE_utildefines.h" -#include "BKE_sound.h" -#include "BKE_writeavi.h" #include "WM_api.h" #include "WM_types.h" @@ -68,7 +62,6 @@ #include "RNA_access.h" #include "RNA_define.h" - #include "wm_window.h" #include "render_intern.h" @@ -136,8 +129,12 @@ void image_buffer_rect_update(Scene *scene, RenderResult *rr, ImBuf *ibuf, volat } if(rectf==NULL) return; - if(ibuf->rect==NULL) - imb_addrectImBuf(ibuf); + if(ibuf->rect==NULL) { + BLI_lock_thread(LOCK_CUSTOM1); + if(ibuf->rect==NULL) + imb_addrectImBuf(ibuf); + BLI_unlock_thread(LOCK_CUSTOM1); + } rectf+= 4*(rr->rectx*ymin + xmin); rectc= (char *)(ibuf->rect + ibuf->x*rymin + rxmin); @@ -391,15 +388,20 @@ static ScrArea *find_empty_image_area(bContext *C) static int screen_render_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); - Render *re= RE_GetRender(scene->id.name, RE_SLOT_VIEW); + Render *re= RE_GetRender(scene->id.name); + Image *ima; View3D *v3d= CTX_wm_view3d(C); int lay= (v3d)? v3d->lay|scene->lay: scene->lay; if(re==NULL) { - re= RE_NewRender(scene->id.name, RE_SLOT_VIEW); + re= RE_NewRender(scene->id.name); } RE_test_break_cb(re, NULL, (int (*)(void *)) blender_test_break); + ima= BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result"); + BKE_image_signal(ima, NULL, IMA_SIGNAL_FREE); + BKE_image_backup_render(scene, ima); + if(RNA_boolean_get(op->ptr, "animation")) RE_BlenderAnim(re, scene, lay, scene->r.sfra, scene->r.efra, scene->r.frame_step, op->reports); else @@ -434,7 +436,7 @@ static void render_freejob(void *rjv) MEM_freeN(rj); } -/* str is IMA_RW_MAXTEXT in size */ +/* str is IMA_MAX_RENDER_TEXT in size */ static void make_renderinfo_string(RenderStats *rs, Scene *scene, char *str) { char info_time_str[32]; // used to be extern to header_info.c @@ -475,7 +477,7 @@ static void make_renderinfo_string(RenderStats *rs, Scene *scene, char *str) spos+= sprintf(spos, "| %s ", rs->infostr); /* very weak... but 512 characters is quite safe */ - if(spos >= str+IMA_RW_MAXTEXT) + if(spos >= str+IMA_MAX_RENDER_TEXT) if (G.f & G_DEBUG) printf("WARNING! renderwin text beyond limit \n"); @@ -484,12 +486,16 @@ static void make_renderinfo_string(RenderStats *rs, Scene *scene, char *str) static void image_renderinfo_cb(void *rjv, RenderStats *rs) { RenderJob *rj= rjv; + RenderResult *rr; + + rr= RE_AcquireResultRead(rj->re); /* malloc OK here, stats_draw is not in tile threads */ - if(rj->image->render_text==NULL) - rj->image->render_text= MEM_callocN(IMA_RW_MAXTEXT, "rendertext"); + if(rr->text==NULL) + rr->text= MEM_callocN(IMA_MAX_RENDER_TEXT, "rendertext"); - make_renderinfo_string(rs, rj->scene, rj->image->render_text); + make_renderinfo_string(rs, rj->scene, rr->text); + RE_ReleaseResult(rj->re); /* make jobs timer to send notifier */ *(rj->do_update)= 1; @@ -630,10 +636,11 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event) /* get a render result image, and make sure it is empty */ ima= BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result"); BKE_image_signal(ima, NULL, IMA_SIGNAL_FREE); + BKE_image_backup_render(rj->scene, ima); rj->image= ima; /* setup new render */ - re= RE_NewRender(scene->id.name, RE_SLOT_VIEW); + re= RE_NewRender(scene->id.name); RE_test_break_cb(re, rj, render_breakjob); RE_display_draw_cb(re, rj, image_rect_update); RE_stats_draw_cb(re, rj, image_renderinfo_cb); diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index 1b1e3114fd8..ee5363a00f9 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -189,7 +189,7 @@ static int screen_opengl_render_init(bContext *C, wmOperator *op) oglrender->iuser.ok= 1; /* create render and render result */ - oglrender->re= RE_NewRender(scene->id.name, RE_SLOT_VIEW); + oglrender->re= RE_NewRender(scene->id.name); RE_InitState(oglrender->re, NULL, &scene->r, NULL, sizex, sizey, NULL); rr= RE_AcquireResultWrite(oglrender->re); diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 2b9526ef635..1a9e70518bc 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -299,6 +299,7 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre sce->r.alphamode= R_ADDSKY; sce->r.cfra= scene->r.cfra; + strcpy(sce->r.engine, scene->r.engine); if(id_type==ID_MA) { Material *mat= (Material *)id; @@ -470,7 +471,7 @@ static int ed_preview_draw_rect(ScrArea *sa, Scene *sce, ID *id, int split, int } } - re= RE_GetRender(name, RE_SLOT_DEFAULT); + re= RE_GetRender(name); RE_AcquireResultImage(re, &rres); if(rres.rectf) { @@ -698,7 +699,7 @@ void BIF_view3d_previewrender(Scene *scene, ScrArea *sa) ri->status= 0; sprintf(name, "View3dPreview %p", sa); - re= ri->re= RE_NewRender(name, RE_SLOT_DEFAULT); + re= ri->re= RE_NewRender(name); //RE_display_draw_cb(re, view3d_previewrender_progress); //RE_stats_draw_cb(re, view3d_previewrender_stats); //RE_test_break_cb(re, qtest); @@ -780,7 +781,7 @@ void BIF_view3d_previewrender(Scene *scene, ScrArea *sa) /* OK, can we enter render code? */ if(ri->status==(PR_DISPRECT|PR_DBASE|PR_PROJECTED|PR_ROTATED)) { //printf("curtile %d tottile %d\n", ri->curtile, ri->tottile); - RE_TileProcessor(ri->re, ri->curtile, 0); + RE_TileProcessor(ri->re); //, ri->curtile, 0); if(ri->rect==NULL) ri->rect= MEM_mallocN(sizeof(int)*ri->pr_rectx*ri->pr_recty, "preview view3d rect"); @@ -885,11 +886,11 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs if(!split || first) sprintf(name, "Preview %p", sp->owner); else sprintf(name, "SecondPreview %p", sp->owner); - re= RE_GetRender(name, RE_SLOT_DEFAULT); + re= RE_GetRender(name); /* full refreshed render from first tile */ if(re==NULL) - re= RE_NewRender(name, RE_SLOT_DEFAULT); + re= RE_NewRender(name); /* sce->r gets copied in RE_InitState! */ sce->r.scemode &= ~(R_MATNODE_PREVIEW|R_TEXNODE_PREVIEW); @@ -915,7 +916,9 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs else sizex= sp->sizex; /* allocates or re-uses render result */ - RE_InitState(re, NULL, &sce->r, NULL, sizex, sp->sizey, NULL); + sce->r.xsch= sizex; + sce->r.ysch= sp->sizey; + sce->r.size= 100; /* callbacs are cleared on GetRender() */ if(sp->pr_method==PR_BUTS_RENDER) { @@ -928,10 +931,7 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs ((Camera *)sce->camera->data)->lens *= (float)sp->sizey/(float)sizex; /* entire cycle for render engine */ - RE_SetCamera(re, sce->camera); - RE_Database_FromScene(re, sce, sce->lay, 1); - RE_TileProcessor(re, 0, 1); // actual render engine - RE_Database_Free(re); + RE_PreviewRender(re, sce); ((Camera *)sce->camera->data)->lens= oldlens; diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 4ec63c3c481..435201f506e 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -49,6 +49,7 @@ #include "WM_types.h" #include "ED_image.h" +#include "ED_view3d.h" #include "ED_screen.h" #include "ED_screen_types.h" @@ -1387,6 +1388,9 @@ void ED_screen_set_scene(bContext *C, Scene *scene) while(sl) { if(sl->spacetype==SPACE_VIEW3D) { View3D *v3d= (View3D*) sl; + + ED_view3d_scene_layers_copy(v3d, scene); + if (!v3d->camera || !object_in_scene(v3d->camera, scene)) { v3d->camera= scene_find_camera(sc->scene); // XXX if (sc==curscreen) handle_view3d_lock(); diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 0b11c1a25f6..509a1bcc61e 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -1852,13 +1852,13 @@ int sculpt_stroke_get_location(bContext *C, struct PaintStroke *stroke, float ou sculpt_stroke_modifiers_check(C, ss); viewline(vc->ar, vc->v3d, mval, ray_start, ray_end); - sub_v3_v3v3(ray_normal, ray_end, ray_start); - dist= normalize_v3(ray_normal); invert_m4_m4(obimat, ss->ob->obmat); mul_m4_v3(obimat, ray_start); - mul_mat3_m4_v3(obimat, ray_normal); - normalize_v3(ray_normal); + mul_m4_v3(obimat, ray_end); + + sub_v3_v3v3(ray_normal, ray_end, ray_start); + dist= normalize_v3(ray_normal); srd.ss = vc->obact->sculpt; srd.ray_start = ray_start; diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index ecbac050712..074e8b6c81b 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -711,8 +711,8 @@ void FILE_OT_next(struct wmOperatorType *ot) int file_next_exec(bContext *C, wmOperator *unused) { SpaceFile *sfile= CTX_wm_space_file(C); - if(sfile->params) { - if (!sfile->folders_next) + if(sfile->params) { + if (!sfile->folders_next) sfile->folders_next = folderlist_new(); folderlist_pushdir(sfile->folders_prev, sfile->params->dir); @@ -777,6 +777,7 @@ int file_directory_new_exec(bContext *C, wmOperator *op) /* now remember file to jump into editing */ BLI_strncpy(sfile->params->renamefile, name, FILE_MAXFILE); + ED_fileselect_clear(C, sfile); WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); return OPERATOR_FINISHED; diff --git a/source/blender/editors/space_file/writeimage.c b/source/blender/editors/space_file/writeimage.c index 39a986aca32..ade0b7db0ca 100644 --- a/source/blender/editors/space_file/writeimage.c +++ b/source/blender/editors/space_file/writeimage.c @@ -86,14 +86,14 @@ static void save_rendered_image_cb_real(char *name, int confirm) if(overwrite) { if(scene->r.imtype==R_MULTILAYER) { - Render *re= RE_GetRender(scene->id.name, RE_SLOT_VIEW); + Render *re= RE_GetRender(scene->id.name); RenderResult *rr= RE_AcquireResultRead(re); if(rr) RE_WriteRenderResult(rr, str, scene->r.quality); RE_ReleaseResult(re); } else { - Render *re= RE_GetRender(scene->id.name, RE_SLOT_VIEW); + Render *re= RE_GetRender(scene->id.name); RenderResult rres; ImBuf *ibuf; @@ -207,7 +207,7 @@ void BIF_save_rendered_image(char *name) /* calls fileselect */ void BIF_save_rendered_image_fs(Scene *scene) { - Render *re= RE_GetRender(scene->id.name, RE_SLOT_VIEW); + Render *re= RE_GetRender(scene->id.name); RenderResult rres; RE_AcquireResultImage(re, &rres); diff --git a/source/blender/editors/space_image/SConscript b/source/blender/editors/space_image/SConscript index 874549e6949..dd43559645d 100644 --- a/source/blender/editors/space_image/SConscript +++ b/source/blender/editors/space_image/SConscript @@ -13,5 +13,8 @@ if env['WITH_BF_LCMS']: defs.append('WITH_LCMS') if env['WITH_BF_OPENEXR']: defs.append('WITH_OPENEXR') + +if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): + incs += ' ' + env['BF_PTHREADS_INC'] env.BlenderLib ( 'bf_editors_space_image', sources, Split(incs), defs, libtype=['core'], priority=[40] ) diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index 283d8490028..9f897c4ff2c 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -527,12 +527,12 @@ static char *slot_menu() char *str; int a, slot; - str= MEM_callocN(RE_SLOT_MAX*32, "menu slots"); + str= MEM_callocN(IMA_MAX_RENDER_SLOT*32, "menu slots"); strcpy(str, "Slot %t"); a= strlen(str); - for(slot=0; slot<RE_SLOT_MAX; slot++) + for(slot=0; slot<IMA_MAX_RENDER_SLOT; slot++) a += sprintf(str+a, "|Slot %d %%x%d", slot+1, slot); return str; @@ -606,7 +606,6 @@ static void image_multi_cb(bContext *C, void *rr_v, void *iuser_v) { ImageUser *iuser= iuser_v; - RE_SetViewSlot(iuser->menunr); BKE_image_multilayer_index(rr_v, iuser); WM_event_add_notifier(C, NC_IMAGE|ND_DRAW, NULL); } @@ -707,7 +706,7 @@ static void image_user_change(bContext *C, void *iuser_v, void *unused) } #endif -static void uiblock_layer_pass_buttons(uiLayout *layout, RenderResult *rr, ImageUser *iuser, int w, int render) +static void uiblock_layer_pass_buttons(uiLayout *layout, RenderResult *rr, ImageUser *iuser, int w, short *render_slot) { uiBlock *block= uiLayoutGetBlock(layout); uiBut *but; @@ -723,10 +722,9 @@ static void uiblock_layer_pass_buttons(uiLayout *layout, RenderResult *rr, Image wmenu3= (3*w)/6; /* menu buts */ - if(render) { + if(render_slot) { strp= slot_menu(); - iuser->menunr= RE_GetViewSlot(); - but= uiDefButS(block, MENU, 0, strp, 0, 0, wmenu1, 20, &iuser->menunr, 0,0,0,0, "Select Slot"); + but= uiDefButS(block, MENU, 0, strp, 0, 0, wmenu1, 20, render_slot, 0,0,0,0, "Select Slot"); uiButSetFunc(but, image_multi_cb, rr, iuser); MEM_freeN(strp); } @@ -745,7 +743,7 @@ static void uiblock_layer_pass_buttons(uiLayout *layout, RenderResult *rr, Image } } -static void uiblock_layer_pass_arrow_buttons(uiLayout *layout, RenderResult *rr, ImageUser *iuser, int render) +static void uiblock_layer_pass_arrow_buttons(uiLayout *layout, RenderResult *rr, ImageUser *iuser, short *render_slot) { uiBlock *block= uiLayoutGetBlock(layout); uiLayout *row; @@ -766,7 +764,7 @@ static void uiblock_layer_pass_arrow_buttons(uiLayout *layout, RenderResult *rr, but= uiDefIconBut(block, BUT, 0, ICON_TRIA_RIGHT, 0,0,18,20, NULL, 0, 0, 0, 0, "Next Layer"); uiButSetFunc(but, image_multi_inclay_cb, rr, iuser); - uiblock_layer_pass_buttons(row, rr, iuser, 230, render); + uiblock_layer_pass_buttons(row, rr, iuser, 230, render_slot); /* decrease, increase arrows */ but= uiDefIconBut(block, BUT, 0, ICON_TRIA_LEFT, 0,0,17,20, NULL, 0, 0, 0, 0, "Previous Pass"); @@ -875,9 +873,9 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propn } else if(ima->type==IMA_TYPE_R_RESULT) { /* browse layer/passes */ - Render *re= RE_GetRender(scene->id.name, RE_SLOT_VIEW); + Render *re= RE_GetRender(scene->id.name); RenderResult *rr= RE_AcquireResultRead(re); - uiblock_layer_pass_arrow_buttons(layout, rr, iuser, 1); + uiblock_layer_pass_arrow_buttons(layout, rr, iuser, &ima->render_slot); RE_ReleaseResult(re); } } @@ -904,7 +902,7 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propn /* multilayer? */ if(ima->type==IMA_TYPE_MULTILAYER && ima->rr) { - uiblock_layer_pass_arrow_buttons(layout, ima->rr, iuser, 0); + uiblock_layer_pass_arrow_buttons(layout, ima->rr, iuser, NULL); } else if(ima->source != IMA_SRC_GENERATED) { if(compact == 0) { @@ -984,7 +982,7 @@ void uiTemplateImageLayers(uiLayout *layout, bContext *C, Image *ima, ImageUser /* render layers and passes */ if(ima && iuser) { rr= BKE_image_acquire_renderresult(scene, ima); - uiblock_layer_pass_buttons(layout, rr, iuser, 160, ima->type==IMA_TYPE_R_RESULT); + uiblock_layer_pass_buttons(layout, rr, iuser, 160, (ima->type==IMA_TYPE_R_RESULT)? &ima->render_slot: NULL); BKE_image_release_renderresult(scene, ima); } } diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index 33dfc99602e..55bec0740ea 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -38,6 +38,7 @@ #include "DNA_screen_types.h" #include "PIL_time.h" +#include "BLI_threads.h" #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" @@ -60,6 +61,8 @@ #include "UI_view2d.h" +#include "RE_pipeline.h" + #include "image_intern.h" #define HEADER_HEIGHT 18 @@ -73,50 +76,51 @@ static void image_verify_buffer_float(SpaceImage *sima, Image *ima, ImBuf *ibuf, NOTE: if float buffer changes, we have to manually remove the rect */ - if(ibuf->rect_float) { - if(ibuf->rect==NULL) { - if (color_manage) { - if (ima && ima->source == IMA_SRC_VIEWER) + if(ibuf->rect_float && ibuf->rect==NULL) { + BLI_lock_thread(LOCK_CUSTOM1); + if(ibuf->rect_float && ibuf->rect==NULL) { + if(color_manage) { + if(ima && ima->source == IMA_SRC_VIEWER) ibuf->profile = IB_PROFILE_LINEAR_RGB; - } else { - ibuf->profile = IB_PROFILE_NONE; } + else + ibuf->profile = IB_PROFILE_NONE; + IMB_rect_from_float(ibuf); } + BLI_unlock_thread(LOCK_CUSTOM1); } } -static void draw_render_info(Image *ima, ARegion *ar) +static void draw_render_info(Scene *scene, Image *ima, ARegion *ar) { + RenderResult *rr; rcti rect; float colf[3]; - int showspare= 0; // XXX BIF_show_render_spare(); - - if(ima->render_text==NULL) - return; - - rect= ar->winrct; - rect.xmin= 0; - rect.ymin= ar->winrct.ymax - ar->winrct.ymin - HEADER_HEIGHT; - rect.xmax= ar->winrct.xmax - ar->winrct.xmin; - rect.ymax= ar->winrct.ymax - ar->winrct.ymin; - /* clear header rect */ - UI_GetThemeColor3fv(TH_BACK, colf); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); - glColor4f(colf[0]+0.1f, colf[1]+0.1f, colf[2]+0.1f, 0.5f); - glRecti(rect.xmin, rect.ymin, rect.xmax, rect.ymax+1); - glDisable(GL_BLEND); - - UI_ThemeColor(TH_TEXT_HI); + rr= BKE_image_acquire_renderresult(scene, ima); - if(showspare) { - UI_DrawString(12, rect.ymin + 5, "(Previous)"); - UI_DrawString(72, rect.ymin + 5, ima->render_text); + if(rr && rr->text) { + rect= ar->winrct; + rect.xmin= 0; + rect.ymin= ar->winrct.ymax - ar->winrct.ymin - HEADER_HEIGHT; + rect.xmax= ar->winrct.xmax - ar->winrct.xmin; + rect.ymax= ar->winrct.ymax - ar->winrct.ymin; + + /* clear header rect */ + UI_GetThemeColor3fv(TH_BACK, colf); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + glColor4f(colf[0]+0.1f, colf[1]+0.1f, colf[2]+0.1f, 0.5f); + glRecti(rect.xmin, rect.ymin, rect.xmax, rect.ymax+1); + glDisable(GL_BLEND); + + UI_ThemeColor(TH_TEXT_HI); + + UI_DrawString(12, rect.ymin + 5, rr->text); } - else - UI_DrawString(12, rect.ymin + 5, ima->render_text); + + BKE_image_release_renderresult(scene, ima); } void draw_image_info(ARegion *ar, int channels, int x, int y, char *cp, float *fp, int *zp, float *zpf) @@ -640,8 +644,8 @@ void draw_image_main(SpaceImage *sima, ARegion *ar, Scene *scene) /* retrieve the image and information about it */ ima= ED_space_image(sima); - ibuf= ED_space_image_acquire_buffer(sima, &lock); ED_space_image_zoom(sima, ar, &zoomx, &zoomy); + ibuf= ED_space_image_acquire_buffer(sima, &lock); show_viewer= (ima && ima->source == IMA_SRC_VIEWER); show_render= (show_viewer && ima->type == IMA_TYPE_R_RESULT); @@ -659,10 +663,7 @@ void draw_image_main(SpaceImage *sima, ARegion *ar, Scene *scene) /* paint helpers */ draw_image_paint_helpers(sima, ar, scene, zoomx, zoomy); - /* render info */ - if(ima && show_render) - draw_render_info(ima, ar); - + /* XXX integrate this code */ #if 0 if(ibuf) { @@ -681,5 +682,9 @@ void draw_image_main(SpaceImage *sima, ARegion *ar, Scene *scene) #endif ED_space_image_release_buffer(sima, lock); + + /* render info */ + if(ima && show_render) + draw_render_info(scene, ima, ar); } diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 671bbe5f8cd..a223e2481fc 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -1979,21 +1979,21 @@ static int cycle_render_slot_poll(bContext *C) static int cycle_render_slot_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); - int a, slot, cur= RE_GetViewSlot(); + Image *ima= CTX_data_edit_image(C); + int a, slot, cur= ima->render_slot; - for(a=1; a<RE_SLOT_MAX; a++) { - slot= (cur+a)%RE_SLOT_MAX; + for(a=1; a<IMA_MAX_RENDER_SLOT; a++) { + slot= (cur+a)%IMA_MAX_RENDER_SLOT; - if(RE_GetRender(scene->id.name, slot)) { - RE_SetViewSlot(slot); + if(ima->renders[slot] || slot == ima->last_render_slot) { + ima->render_slot= slot; break; } } - if(a == RE_SLOT_MAX) - RE_SetViewSlot((cur == 1)? 0: 1); - + if(a == IMA_MAX_RENDER_SLOT) + ima->render_slot= ((cur == 1)? 0: 1); + WM_event_add_notifier(C, NC_IMAGE|ND_DRAW, NULL); return OPERATOR_FINISHED; diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index eeab6a7f31e..69b2cb95a9d 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -1650,7 +1650,7 @@ void node_read_renderlayers(SpaceNode *snode) void node_read_fullsamplelayers(SpaceNode *snode) { Scene *curscene= NULL; // XXX - Render *re= RE_NewRender(curscene->id.name, RE_SLOT_VIEW); + Render *re= RE_NewRender(curscene->id.name); WM_cursor_wait(1); diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c index b091c4281c9..9fa64c4e155 100644 --- a/source/blender/editors/space_view3d/drawvolume.c +++ b/source/blender/editors/space_view3d/drawvolume.c @@ -240,6 +240,11 @@ void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture float size[3]; + if(!tex) { + printf("Could not allocate 3D texture for 3D View smoke drawing.\n"); + return; + } + tstart(); VECSUB(size, max, min); @@ -365,7 +370,7 @@ void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture glProgramLocalParameter4fARB (GL_FRAGMENT_PROGRAM_ARB, 1, 7.0, 7.0, 7.0, 1.0); } else - printf("Your gfx card does not support 3dview smoke drawing.\n"); + printf("Your gfx card does not support 3D View smoke drawing.\n"); GPU_texture_bind(tex, 0); if(tex_shadow) diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 798a6949433..543af197370 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -66,6 +66,7 @@ #include "ED_screen.h" #include "ED_armature.h" +#include "GPU_draw.h" #include "PIL_time.h" /* smoothview */ @@ -1415,6 +1416,11 @@ static void copy_view3d_lock_space(View3D *v3d, Scene *scene) } } +void ED_view3d_scene_layers_copy(struct View3D *v3d, struct Scene *scene) +{ + copy_view3d_lock_space(v3d, scene); +} + void ED_view3d_scene_layers_update(Main *bmain, Scene *scene) { bScreen *sc; diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 5c3d133f523..247de5ab338 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1459,7 +1459,6 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int t->launch_event = LEFTMOUSE; } - if (!initTransInfo(C, t, op, event)) // internal data, mouse, vectors { return 0; @@ -3825,7 +3824,7 @@ void initBevelWeight(TransInfo *t) t->num.increment = t->snap[1]; - t->flag |= T_NO_CONSTRAINT; + t->flag |= T_NO_CONSTRAINT|T_NO_PROJECT; } int BevelWeight(TransInfo *t, short mval[2]) @@ -3898,7 +3897,7 @@ void initCrease(TransInfo *t) t->num.increment = t->snap[1]; - t->flag |= T_NO_CONSTRAINT; + t->flag |= T_NO_CONSTRAINT|T_NO_PROJECT; } int Crease(TransInfo *t, short mval[2]) diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 3fe61bbe851..8264bc7c0b0 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -379,6 +379,9 @@ typedef struct TransInfo { /* to specificy if we save back settings at the end */ #define T_MODAL (1 << 21) + /* no retopo */ +#define T_NO_PROJECT (1 << 22) + /* TransInfo->modifiers */ #define MOD_CONSTRAINT_SELECT 0x01 #define MOD_PRECISION 0x02 diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index e7e2ba6ce76..b49e1b05de3 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -233,7 +233,7 @@ int handleSnapping(TransInfo *t, wmEvent *event) void applyProject(TransInfo *t) { /* XXX FLICKER IN OBJECT MODE */ - if ((t->tsnap.project) && activeSnap(t)) + if ((t->tsnap.project) && activeSnap(t) && (t->flag & T_NO_PROJECT) == 0) { TransData *td = t->data; float tvec[3]; diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp index 7672a448bba..e85a685de98 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp @@ -327,7 +327,7 @@ Render* BlenderStrokeRenderer::RenderScene( Render *re ) { freestyle_scene->r.planes = R_PLANES32; freestyle_scene->r.imtype = R_PNG; - Render *freestyle_render = RE_NewRender(freestyle_scene->id.name, RE_SLOT_DEFAULT); + Render *freestyle_render = RE_NewRender(freestyle_scene->id.name); RE_RenderFreestyleStrokes(freestyle_render, freestyle_scene); return freestyle_render; diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c index 4b735a8bd84..8e0a23ccfeb 100644 --- a/source/blender/gpu/intern/gpu_extensions.c +++ b/source/blender/gpu/intern/gpu_extensions.c @@ -392,6 +392,9 @@ GPUTexture *GPU_texture_create_3D(int w, int h, int depth, float *fpixels) void *pixels = NULL; float vfBorderColor[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + if(!GLEW_VERSION_1_2) + return NULL; + tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture"); tex->w = w; tex->h = h; diff --git a/source/blender/makesdna/DNA_image_types.h b/source/blender/makesdna/DNA_image_types.h index 3a7933cf425..5aed1d0c2d0 100644 --- a/source/blender/makesdna/DNA_image_types.h +++ b/source/blender/makesdna/DNA_image_types.h @@ -72,9 +72,12 @@ typedef struct Image { /* sources from: */ struct anim *anim; struct RenderResult *rr; + + struct RenderResult *renders[8]; /* IMA_MAX_RENDER_SLOT */ + short render_slot, last_render_slot; short ok, flag; - short source, type, pad, pad1; + short source, type; int lastframe; /* texture page */ @@ -87,14 +90,13 @@ typedef struct Image { struct PackedFile * packedfile; struct PreviewImage * preview; - /* not saved in file, statistics for render result */ - char *render_text; - + /* game engine tile animation */ float lastupdate; int lastused; short animspeed; - short gen_x, gen_y, gen_type; /* for generated images */ + /* for generated images */ + short gen_x, gen_y, gen_type; /* display aspect - for UV editing images resized for faster openGL display */ float aspx, aspy; @@ -124,9 +126,9 @@ typedef struct Image { /* ima->type and ima->source moved to BKE_image.h, for API */ -/* render_text maxlen */ -#define IMA_RW_MAXTEXT 512 - +/* render */ +#define IMA_MAX_RENDER_TEXT 512 +#define IMA_MAX_RENDER_SLOT 8 #endif diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c index 710a22ba17a..d00507e8bcf 100644 --- a/source/blender/makesrna/intern/rna_render.c +++ b/source/blender/makesrna/intern/rna_render.c @@ -207,14 +207,12 @@ static int rna_RenderPass_rect_get_length(PointerRNA *ptr, int length[RNA_MAX_AR static void rna_RenderPass_rect_get(PointerRNA *ptr, float *values) { RenderPass *rpass= (RenderPass*)ptr->data; - printf("rect get\n"); memcpy(values, rpass->rect, sizeof(float)*rpass->rectx*rpass->recty*rpass->channels); } static void rna_RenderPass_rect_set(PointerRNA *ptr, const float *values) { RenderPass *rpass= (RenderPass*)ptr->data; - printf("rect set\n"); memcpy(rpass->rect, values, sizeof(float)*rpass->rectx*rpass->recty*rpass->channels); } @@ -279,6 +277,14 @@ static void rna_def_render_engine(BlenderRNA *brna) RNA_def_property_string_sdna(prop, NULL, "type->name"); RNA_def_property_flag(prop, PROP_REGISTER); + prop= RNA_def_property(srna, "bl_preview", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "type->flag", RE_DO_PREVIEW); + RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL); + + prop= RNA_def_property(srna, "bl_postprocess", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "type->flag", RE_DO_ALL); + RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL); + RNA_define_verify_sdna(1); } diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_composite.c b/source/blender/nodes/intern/CMP_nodes/CMP_composite.c index 9a302527a61..7510a2d11d4 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_composite.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_composite.c @@ -50,7 +50,7 @@ static void node_composit_exec_composite(void *data, bNode *node, bNodeStack **i RenderData *rd= data; if(scene && (rd->scemode & R_DOCOMP)) { - Render *re= RE_GetRender(scene->id.name, RE_SLOT_RENDERING); + Render *re= RE_GetRender(scene->id.name); RenderResult *rr= RE_AcquireResultWrite(re); if(rr) { CompBuf *outbuf, *zbuf=NULL; diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_image.c b/source/blender/nodes/intern/CMP_nodes/CMP_image.c index be91eb61587..f53e3d2ba8f 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_image.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_image.c @@ -354,7 +354,7 @@ void node_composit_rlayers_out(RenderData *rd, RenderLayer *rl, bNodeStack **out static void node_composit_exec_rlayers(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { Scene *sce= (Scene *)node->id; - Render *re= (sce)? RE_GetRender(sce->id.name, RE_SLOT_RENDERING): NULL; + Render *re= (sce)? RE_GetRender(sce->id.name): NULL; RenderData *rd= data; RenderResult *rr= NULL; diff --git a/source/blender/python/doc/epy/BGL.py b/source/blender/python/doc/epy/BGL.py index b054e762273..ce148dc72ba 100644 --- a/source/blender/python/doc/epy/BGL.py +++ b/source/blender/python/doc/epy/BGL.py @@ -318,6 +318,34 @@ def glCopyPixels(x, y, width, height, type): @type type: Enumerated constant @param type: Specifies whether color values, depth values, or stencil values are to be copied. """ + + def glCopyTexImage2D(target, level, internalformat, x, y, width, height, border): + """ + Copy pixels into a 2D texture image + @see: U{www.opengl.org/sdk/docs/man/xhtml/glCopyTexImage2D.xml} + + @type target: Enumerated constant + @param target: Specifies the target texture. + @type level: int + @param level: Specifies the level-of-detail number. Level 0 is the base image level. + Level n is the nth mipmap reduction image. + @type internalformat: int + @param internalformat: Specifies the number of color components in the texture. + @type width: int + @type x, y: int + @param x, y:Specify the window coordinates of the first pixel that is copied + from the frame buffer. This location is the lower left corner of a rectangular + block of pixels. + @param width: Specifies the width of the texture image. Must be 2n+2(border) for + some integer n. All implementations support texture images that are at least 64 + texels wide. + @type height: int + @param height: Specifies the height of the texture image. Must be 2m+2(border) for + some integer m. All implementations support texture images that are at least 64 + texels high. + @type border: int + @param border: Specifies the width of the border. Must be either 0 or 1. + """ def glCullFace(mode): """ diff --git a/source/blender/python/generic/bgl.c b/source/blender/python/generic/bgl.c index 2ca84f3a311..63c518c8721 100644 --- a/source/blender/python/generic/bgl.c +++ b/source/blender/python/generic/bgl.c @@ -355,7 +355,10 @@ static int Buffer_ass_slice(PyObject *self, int begin, int end, PyObject *seq) } if (PySequence_Length(seq)!=(end-begin)) { - PyErr_SetString(PyExc_TypeError, "size mismatch in assignment"); + int seq_len = PySequence_Length(seq); + char err_str[128]; + sprintf(err_str, "size mismatch in assignment. Expected size: %d (size provided: %d)", seq_len, (end-begin)); + PyErr_SetString(PyExc_TypeError, err_str); return -1; } @@ -476,6 +479,7 @@ BGL_Wrap(1, Color4usv, void, (GLushortP)) BGL_Wrap(4, ColorMask, void, (GLboolean, GLboolean, GLboolean, GLboolean)) BGL_Wrap(2, ColorMaterial, void, (GLenum, GLenum)) BGL_Wrap(5, CopyPixels, void, (GLint, GLint, GLsizei, GLsizei, GLenum)) +BGL_Wrap(8, CopyTexImage2D, void, (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint)) BGL_Wrap(1, CullFace, void, (GLenum)) BGL_Wrap(2, DeleteLists, void, (GLuint, GLsizei)) BGL_Wrap(2, DeleteTextures, void, (GLsizei, GLuintP)) @@ -819,6 +823,7 @@ static struct PyMethodDef BGL_methods[] = { MethodDef(ColorMask), MethodDef(ColorMaterial), MethodDef(CopyPixels), + MethodDef(CopyTexImage2D), MethodDef(CullFace), MethodDef(DeleteLists), MethodDef(DeleteTextures), diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h index 09d190b836f..cdf9cc3fb2e 100644 --- a/source/blender/render/extern/include/RE_pipeline.h +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -129,6 +129,9 @@ typedef struct RenderResult { /* for render results in Image, verify validity for sequences */ int framenr; + + /* render info text */ + char *text; } RenderResult; @@ -146,21 +149,8 @@ typedef struct RenderStats { /* the name is used as identifier, so elsewhere in blender the result can retrieved */ /* calling a new render with same name, frees automatic existing render */ -struct Render *RE_NewRender (const char *name, int slot); -struct Render *RE_GetRender(const char *name, int slot); - -/* render slots. for most cases like baking or preview render this will - always be default, for actual render multiple slots can be used. in - that case 'rendering' is the slot being rendered to, and 'view' is the - slot being viewed. these are always the same except if the currently - viewed slot is changed during render, at the end they will be synced. */ -#define RE_SLOT_RENDERING -2 -#define RE_SLOT_VIEW -1 -#define RE_SLOT_DEFAULT 0 -#define RE_SLOT_MAX 10 - -void RE_SetViewSlot(int slot); -int RE_GetViewSlot(void); +struct Render *RE_NewRender (const char *name); +struct Render *RE_GetRender(const char *name); /* returns 1 while render is working (or renders called from within render) */ int RE_RenderInProgress(struct Render *re); @@ -177,6 +167,7 @@ struct RenderResult *RE_AcquireResultWrite(struct Render *re); void RE_ReleaseResult(struct Render *re); void RE_AcquireResultImage(struct Render *re, struct RenderResult *rr); void RE_ReleaseResultImage(struct Render *re); +void RE_SwapResult(struct Render *re, struct RenderResult **rr); struct RenderStats *RE_GetStats(struct Render *re); void RE_ResultGet32(struct Render *re, unsigned int *rect); struct RenderLayer *RE_GetRenderLayer(struct RenderResult *rr, const char *name); @@ -211,13 +202,16 @@ void RE_set_max_threads(int threads); void RE_init_threadcount(Render *re); /* the main processor, assumes all was set OK! */ -void RE_TileProcessor(struct Render *re, int firsttile, int threaded); +void RE_TileProcessor(struct Render *re); /* only RE_NewRender() needed, main Blender render calls */ void RE_BlenderFrame(struct Render *re, struct Scene *scene, struct SceneRenderLayer *srl, unsigned int lay, int frame); void RE_BlenderAnim(struct Render *re, struct Scene *scene, unsigned int lay, int sfra, int efra, int tfra, struct ReportList *reports); void RE_RenderFreestyleStrokes(struct Render *re, struct Scene *scene); +/* main preview render call */ +void RE_PreviewRender(struct Render *re, struct Scene *scene); + void RE_ReadRenderResult(struct Scene *scene, struct Scene *scenode); void RE_WriteRenderResult(RenderResult *rr, char *filename, int compress); struct RenderResult *RE_MultilayerConvert(void *exrhandle, int rectx, int recty); @@ -260,8 +254,10 @@ struct Scene *RE_GetScene(struct Render *re); /* External Engine */ -#define RE_INTERNAL 1 -#define RE_GAME 2 +#define RE_INTERNAL 1 +#define RE_GAME 2 +#define RE_DO_PREVIEW 4 +#define RE_DO_ALL 8 extern ListBase R_engines; diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 727f490e31f..db242b0b1d9 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -5727,7 +5727,7 @@ void RE_make_sticky(Scene *scene, View3D *v3d) return; } - re= RE_NewRender("_make sticky_", RE_SLOT_DEFAULT); + re= RE_NewRender("_make sticky_"); RE_InitState(re, NULL, &scene->r, NULL, scene->r.xsch, scene->r.ysch, NULL); /* use renderdata and camera to set viewplane */ diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index 73c9aaf6642..1a34868b9fd 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -122,7 +122,7 @@ static Render *envmap_render_copy(Render *re, EnvMap *env) Render *envre; int cuberes; - envre= RE_NewRender("Envmap", RE_SLOT_DEFAULT); + envre= RE_NewRender("Envmap"); env->lastsize= re->r.size; cuberes = (env->cuberes * re->r.size) / 100; @@ -447,7 +447,7 @@ static void render_envmap(Render *re, EnvMap *env) env_set_imats(envre); if(re->test_break(re->tbh)==0) { - RE_TileProcessor(envre, 0, 0); + RE_TileProcessor(envre); } /* rotate back */ diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 0a1c63ba114..e654043931c 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -114,12 +114,9 @@ static struct { ListBase renderlist; - /* render slots */ - int viewslot, renderingslot; - /* commandline thread override */ int threads; -} RenderGlobal = {{NULL, NULL}, 0, 0, -1}; +} RenderGlobal = {{NULL, NULL}, -1}; /* hardcopy of current render, used while rendering for speed */ Render R; @@ -194,6 +191,8 @@ void RE_FreeRenderResult(RenderResult *res) MEM_freeN(res->rectz); if(res->rectf) MEM_freeN(res->rectf); + if(res->text) + MEM_freeN(res->text); MEM_freeN(res); } @@ -982,38 +981,15 @@ static void read_render_result(Render *re, int sample) /* *************************************************** */ -void RE_SetViewSlot(int slot) -{ - RenderGlobal.viewslot = slot; -} - -int RE_GetViewSlot(void) -{ - return RenderGlobal.viewslot; -} - -static int re_get_slot(int slot) -{ - if(slot == RE_SLOT_VIEW) - return RenderGlobal.viewslot; - else if(slot == RE_SLOT_RENDERING) - return (G.rendering)? RenderGlobal.renderingslot: RenderGlobal.viewslot; - - return slot; -} - -Render *RE_GetRender(const char *name, int slot) +Render *RE_GetRender(const char *name) { Render *re; - slot= re_get_slot(slot); - /* search for existing renders */ - for(re= RenderGlobal.renderlist.first; re; re= re->next) { - if(strncmp(re->name, name, RE_MAXNAME)==0 && re->slot==slot) { + for(re= RenderGlobal.renderlist.first; re; re= re->next) + if(strncmp(re->name, name, RE_MAXNAME)==0) break; - } - } + return re; } @@ -1038,6 +1014,15 @@ RenderResult *RE_AcquireResultWrite(Render *re) return NULL; } +void RE_SwapResult(Render *re, RenderResult **rr) +{ + /* for keeping render buffers */ + if(re) { + SWAP(RenderResult*, re->result, *rr); + } +} + + void RE_ReleaseResult(Render *re) { if(re) @@ -1148,21 +1133,18 @@ RenderStats *RE_GetStats(Render *re) return &re->i; } -Render *RE_NewRender(const char *name, int slot) +Render *RE_NewRender(const char *name) { Render *re; - slot= re_get_slot(slot); - /* only one render per name exists */ - re= RE_GetRender(name, slot); + re= RE_GetRender(name); if(re==NULL) { /* new render data struct */ re= MEM_callocN(sizeof(Render), "new render"); BLI_addtail(&RenderGlobal.renderlist, re); strncpy(re->name, name, RE_MAXNAME); - re->slot= slot; BLI_rw_mutex_init(&re->resultmutex); } @@ -1478,61 +1460,6 @@ static void *do_part_thread(void *pa_v) return NULL; } -/* returns with render result filled, not threaded, used for preview now only */ -static void render_tile_processor(Render *re, int firsttile) -{ - RenderPart *pa; - - if(re->test_break(re->tbh)) - return; - - BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - - /* hrmf... exception, this is used for preview render, re-entrant, so render result has to be re-used */ - if(re->result==NULL || re->result->layers.first==NULL) { - if(re->result) RE_FreeRenderResult(re->result); - re->result= new_render_result(re, &re->disprect, 0, RR_USEMEM); - } - - BLI_rw_mutex_unlock(&re->resultmutex); - - re->stats_draw(re->sdh, &re->i); - - if(re->result==NULL) - return; - - initparts(re); - - /* assuming no new data gets added to dbase... */ - R= *re; - - for(pa= re->parts.first; pa; pa= pa->next) { - if(firsttile) { - re->i.partsdone++; /* was reset in initparts */ - firsttile--; - } - else { - do_part_thread(pa); - - if(pa->result) { - if(!re->test_break(re->tbh)) { - if(render_display_draw_enabled(re)) - re->display_draw(re->ddh, pa->result, NULL); - - re->i.partsdone++; - re->stats_draw(re->sdh, &re->i); - } - RE_FreeRenderResult(pa->result); - pa->result= NULL; - } - if(re->test_break(re->tbh)) - break; - } - } - - freeparts(re); -} - /* calculus for how much 1 pixel rendered should rotate the 3d geometry */ /* is not that simple, needs to be corrected for errors of larger viewplane sizes */ /* called in initrender.c, initparts() and convertblender.c, for speedvectors */ @@ -1806,44 +1733,21 @@ static void threaded_tile_processor(Render *re) } /* currently only called by preview renders and envmap */ -void RE_TileProcessor(Render *re, int firsttile, int threaded) +void RE_TileProcessor(Render *re) { - /* the partsdone variable has to be reset to firsttile, to survive esc before it was set to zero */ - - re->i.partsdone= firsttile; - - if(!re->sss_points) - re->i.starttime= PIL_check_seconds_timer(); - - if(threaded) - threaded_tile_processor(re); - else - render_tile_processor(re, firsttile); - - if(!re->sss_points) - re->i.lastframetime= PIL_check_seconds_timer()- re->i.starttime; - re->stats_draw(re->sdh, &re->i); + threaded_tile_processor(re); } - /* ************ This part uses API, for rendering Blender scenes ********** */ -static void external_render_3d(Render *re, RenderEngineType *type); +static int external_render_3d(Render *re, int do_all); static void add_freestyle(Render *re); static void do_render_3d(Render *re) { - RenderEngineType *type; - /* try external */ - for(type=R_engines.first; type; type=type->next) - if(strcmp(type->idname, re->r.engine) == 0) - break; - - if(type && type->render) { - external_render_3d(re, type); + if(external_render_3d(re, 0)) return; - } /* internal */ @@ -2211,7 +2115,7 @@ static void do_render_fields_blur_3d(Render *re) */ static void render_scene(Render *re, Scene *sce, int cfra) { - Render *resc= RE_NewRender(sce->id.name, RE_SLOT_RENDERING); + Render *resc= RE_NewRender(sce->id.name); int winx= re->winx, winy= re->winy; sce->r.cfra= cfra; @@ -2563,7 +2467,7 @@ static void do_render_composite_fields_blur_3d(Render *re) static void renderresult_stampinfo(Scene *scene) { RenderResult rres; - Render *re= RE_GetRender(scene->id.name, RE_SLOT_RENDERING); + Render *re= RE_GetRender(scene->id.name); /* this is the basic trick to get the displayed float or char rect from render result */ RE_AcquireResultImage(re, &rres); @@ -2648,8 +2552,11 @@ static void do_render_all_options(Render *re) /* ensure no images are in memory from previous animated sequences */ BKE_image_all_free_anim_ibufs(re->r.cfra); - - if((re->r.scemode & R_DOSEQ) && re->scene->ed && re->scene->ed->seqbase.first) { + + if(external_render_3d(re, 1)) { + /* in this case external render overrides all */ + } + else if((re->r.scemode & R_DOSEQ) && re->scene->ed && re->scene->ed->seqbase.first) { /* note: do_render_seq() frees rect32 when sequencer returns float images */ if(!re->test_break(re->tbh)) do_render_seq(re); @@ -2869,7 +2776,6 @@ static int render_initialize_from_scene(Render *re, Scene *scene, SceneRenderLay void RE_BlenderFrame(Render *re, Scene *scene, SceneRenderLayer *srl, unsigned int lay, int frame) { /* ugly global still... is to prevent preview events and signal subsurfs etc to make full resol */ - RenderGlobal.renderingslot= re->slot; G.rendering= 1; scene->r.cfra= frame; @@ -2880,7 +2786,6 @@ void RE_BlenderFrame(Render *re, Scene *scene, SceneRenderLayer *srl, unsigned i /* UGLY WARNING */ G.rendering= 0; - RenderGlobal.renderingslot= RenderGlobal.viewslot; } void RE_RenderFreestyleStrokes(Render *re, Scene *scene) @@ -2993,7 +2898,6 @@ void RE_BlenderAnim(Render *re, Scene *scene, unsigned int lay, int sfra, int ef /* ugly global still... is to prevent renderwin events and signal subsurfs etc to make full resol */ /* is also set by caller renderwin.c */ G.rendering= 1; - RenderGlobal.renderingslot= re->slot; if(BKE_imtype_is_movie(scene->r.imtype)) if(!mh->start_movie(scene, &re->r, re->rectx, re->recty, reports)) @@ -3090,7 +2994,23 @@ void RE_BlenderAnim(Render *re, Scene *scene, unsigned int lay, int sfra, int ef /* UGLY WARNING */ G.rendering= 0; - RenderGlobal.renderingslot= RenderGlobal.viewslot; +} + +void RE_PreviewRender(Render *re, Scene *sce) +{ + int winx, winy; + + winx= (sce->r.size*sce->r.xsch)/100; + winy= (sce->r.size*sce->r.ysch)/100; + + RE_InitState(re, NULL, &sce->r, NULL, winx, winy, NULL); + + re->scene = sce; + re->lay = sce->lay; + + RE_SetCamera(re, sce->camera); + + do_render_3d(re); } /* note; repeated win/disprect calc... solve that nicer, also in compo */ @@ -3124,9 +3044,9 @@ void RE_ReadRenderResult(Scene *scene, Scene *scenode) scene= scenode; /* get render: it can be called from UI with draw callbacks */ - re= RE_GetRender(scene->id.name, RE_SLOT_VIEW); + re= RE_GetRender(scene->id.name); if(re==NULL) - re= RE_NewRender(scene->id.name, RE_SLOT_VIEW); + re= RE_NewRender(scene->id.name); RE_InitState(re, NULL, &scene->r, NULL, winx, winy, &disprect); re->scene= scene; @@ -3298,10 +3218,24 @@ void RE_result_load_from_file(RenderResult *result, ReportList *reports, char *f } } -static void external_render_3d(Render *re, RenderEngineType *type) +static int external_render_3d(Render *re, int do_all) { + RenderEngineType *type; RenderEngine engine; + for(type=R_engines.first; type; type=type->next) + if(strcmp(type->idname, re->r.engine) == 0) + break; + + if(!(type && type->render)) + return 0; + if((re->r.scemode & R_PREVIEWBUTS) && !(type->flag & RE_DO_PREVIEW)) + return 0; + if(do_all && !(type->flag & RE_DO_ALL)) + return 0; + if(!do_all && (type->flag & RE_DO_ALL)) + return 0; + BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); if(re->result==NULL || !(re->r.scemode & R_PREVIEWBUTS)) { RE_FreeRenderResult(re->result); @@ -3314,7 +3248,7 @@ static void external_render_3d(Render *re, RenderEngineType *type) BLI_rw_mutex_unlock(&re->resultmutex); if(re->result==NULL) - return; + return 1; /* external */ memset(&engine, 0, sizeof(engine)); @@ -3342,5 +3276,7 @@ static void external_render_3d(Render *re, RenderEngineType *type) read_render_result(re, 0); } BLI_rw_mutex_unlock(&re->resultmutex); + + return 1; } diff --git a/source/blender/render/intern/source/sss.c b/source/blender/render/intern/source/sss.c index 6bc1153f8b3..836a60ef4f9 100644 --- a/source/blender/render/intern/source/sss.c +++ b/source/blender/render/intern/source/sss.c @@ -878,7 +878,7 @@ static void sss_create_tree_mat(Render *re, Material *mat) re->result= NULL; BLI_rw_mutex_unlock(&re->resultmutex); - RE_TileProcessor(re, 0, 1); + RE_TileProcessor(re); BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); if(!(re->r.scemode & R_PREVIEWBUTS)) { diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index ea41f03d864..150e6db35cb 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -1057,7 +1057,9 @@ void WM_cursor_warp(wmWindow *win, int x, int y) if (win && win->ghostwin) { int oldx=x, oldy=y; +#if !defined(__APPLE__) || !defined(GHOST_COCOA) y= win->sizey -y - 1; +#endif GHOST_ClientToScreen(win->ghostwin, x, y, &x, &y); GHOST_SetCursorPosition(g_system, x, y); diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index c41a22e966c..db12cd10dfb 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -36,6 +36,7 @@ struct ARegion; struct ARegionType; struct Base; +struct bNodeTree; struct CSG_FaceIteratorDescriptor; struct CSG_VertexIteratorDescriptor; struct ColorBand; @@ -79,7 +80,7 @@ struct wmKeyConfig; struct wmKeyMap; struct wmOperator; struct wmWindowManager; - +struct View3D; /*new render funcs */ @@ -122,6 +123,7 @@ void texture_rgb_blend(float *in, float *tex, float *out, float fact, float facg char stipple_quarttone[1]; //GLubyte stipple_quarttone[128] double elbeemEstimateMemreq(int res, float sx, float sy, float sz, int refine, char *retstr) {return 0.0f;} struct Render *RE_NewRender(const char *name){return (struct Render*) NULL;} +void RE_SwapResult(struct Render *re, struct RenderResult **rr){} void RE_BlenderFrame(struct Render *re, struct Scene *scene, int frame){} /* rna */ diff --git a/source/creator/creator.c b/source/creator/creator.c index 536d380fdbc..b4158483cef 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -681,7 +681,7 @@ static int render_frame(int argc, char **argv, void *data) if (argc > 1) { int frame = atoi(argv[1]); - Render *re = RE_NewRender(scene->id.name, RE_SLOT_DEFAULT); + Render *re = RE_NewRender(scene->id.name); ReportList reports; BKE_reports_init(&reports, RPT_PRINT); @@ -705,7 +705,7 @@ static int render_animation(int argc, char **argv, void *data) bContext *C = data; if (CTX_data_scene(C)) { Scene *scene= CTX_data_scene(C); - Render *re= RE_NewRender(scene->id.name, RE_SLOT_DEFAULT); + Render *re= RE_NewRender(scene->id.name); ReportList reports; BKE_reports_init(&reports, RPT_PRINT); RE_BlenderAnim(re, scene, scene->lay, scene->r.sfra, scene->r.efra, scene->r.frame_step, &reports); @@ -798,6 +798,7 @@ static int run_python(int argc, char **argv, void *data) /* XXX, temp setting the WM is ugly, splash also does this :S */ wmWindowManager *wm= CTX_wm_manager(C); wmWindow *prevwin= CTX_wm_window(C); + Scene *prevscene= CTX_data_scene(C); if(wm->windows.first) { CTX_wm_window_set(C, wm->windows.first); @@ -810,6 +811,9 @@ static int run_python(int argc, char **argv, void *data) fprintf(stderr, "Python script \"%s\" running with missing context data.\n", argv[1]); BPY_run_python_script(C, filename, NULL, NULL); // use reports? } + + CTX_data_scene_set(C, prevscene); + return 1; } else { printf("\nError: you must specify a Python script after '-P '.\n"); diff --git a/source/gameengine/Converter/BL_ArmatureObject.cpp b/source/gameengine/Converter/BL_ArmatureObject.cpp index 7a6fc044637..18204d1deab 100644 --- a/source/gameengine/Converter/BL_ArmatureObject.cpp +++ b/source/gameengine/Converter/BL_ArmatureObject.cpp @@ -89,6 +89,7 @@ void game_copy_pose(bPose **dst, bPose *src, int copy_constraint) } out= (bPose*)MEM_dupallocN(src); + out->chanhash = NULL; out->agroups.first= out->agroups.last= NULL; out->ikdata = NULL; out->ikparam = MEM_dupallocN(out->ikparam); @@ -120,7 +121,8 @@ void game_copy_pose(bPose **dst, bPose *src, int copy_constraint) } BLI_ghash_free(ghash, NULL, NULL); - + // set acceleration structure for channel lookup + make_pose_channels_hash(out); *dst=out; } diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index dfac6e1b816..a13cd71fdac 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -285,6 +285,7 @@ void KX_KetsjiEngine::RenderDome() return; KX_SceneList::iterator sceneit; + KX_Scene* scene; int n_renders=m_dome->GetNumberRenders();// usually 4 or 6 for (int i=0;i<n_renders;i++){ @@ -292,7 +293,7 @@ void KX_KetsjiEngine::RenderDome() for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++) // for each scene, call the proceed functions { - KX_Scene* scene = *sceneit; + scene = *sceneit; KX_Camera* cam = scene->GetActiveCamera(); m_rendertools->BeginFrame(m_rasterizer); @@ -368,6 +369,10 @@ void KX_KetsjiEngine::RenderDome() ); } m_dome->Draw(); + // Draw Callback for the last scene +#ifndef DISABLE_PYTHON + scene->RunDrawingCallbacks(scene->GetPostDrawCB()); +#endif EndFrame(); } diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index c4b1aaeacf4..5bcaa3ee01e 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -1887,6 +1887,8 @@ PyMethodDef KX_Scene::Methods[] = { KX_PYMETHODTABLE(KX_Scene, end), KX_PYMETHODTABLE(KX_Scene, restart), KX_PYMETHODTABLE(KX_Scene, replace), + KX_PYMETHODTABLE(KX_Scene, suspend), + KX_PYMETHODTABLE(KX_Scene, resume), /* dict style access */ KX_PYMETHODTABLE(KX_Scene, get), @@ -2193,6 +2195,24 @@ KX_PYMETHODDEF_DOC(KX_Scene, replace, Py_RETURN_NONE; } +KX_PYMETHODDEF_DOC(KX_Scene, suspend, + "suspend()\n" + "Suspends this scene.\n") +{ + Suspend(); + + Py_RETURN_NONE; +} + +KX_PYMETHODDEF_DOC(KX_Scene, resume, + "resume()\n" + "Resumes this scene.\n") +{ + Resume(); + + Py_RETURN_NONE; +} + /* Matches python dict.get(key, [default]) */ KX_PYMETHODDEF_DOC(KX_Scene, get, "") { diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h index 5b562977837..407f3f1cf1a 100644 --- a/source/gameengine/Ketsji/KX_Scene.h +++ b/source/gameengine/Ketsji/KX_Scene.h @@ -547,6 +547,8 @@ public: KX_PYMETHOD_DOC(KX_Scene, end); KX_PYMETHOD_DOC(KX_Scene, restart); KX_PYMETHOD_DOC(KX_Scene, replace); + KX_PYMETHOD_DOC(KX_Scene, suspend); + KX_PYMETHOD_DOC(KX_Scene, resume); KX_PYMETHOD_DOC(KX_Scene, get); /* attributes */ diff --git a/source/gameengine/PyDoc/GameTypes.py b/source/gameengine/PyDoc/GameTypes.py index 7ecae944324..ffd6a7eeee3 100644 --- a/source/gameengine/PyDoc/GameTypes.py +++ b/source/gameengine/PyDoc/GameTypes.py @@ -3896,6 +3896,16 @@ class KX_Scene(PyObjectPlus): @param scene: The name of the scene to replace this scene with. @type scene: string """ + + def suspend(): + """ + Suspends this scene. + """ + + def resume(): + """ + Resume this scene. + """ def get(key, default=None): """ diff --git a/source/gameengine/PyDoc/VideoTexture.py b/source/gameengine/PyDoc/VideoTexture.py index 8f8ad28e32e..73809a7a15c 100644 --- a/source/gameengine/PyDoc/VideoTexture.py +++ b/source/gameengine/PyDoc/VideoTexture.py @@ -23,15 +23,15 @@ The principle is simple: first you identify a texture on an existing object usin the L{materialID} function, then you create a new texture with dynamic content and swap the two textures in the GPU. The GE is not aware of the substitution and continues to display the object as always, -except that you are now in control of the texture. At the end, the new texture is -deleted and the old texture restored. +except that you are now in control of the texture. When the texture object is deleted, +the new texture is deleted and the old texture restored. Example: import VideoTexture import GameLogic contr = GameLogic.getCurrentController() - obj = contr.getOwner() + obj = contr.owner # the creation of the texture must be done once: save the # texture object in an attribute of GameLogic module makes it persistent @@ -62,13 +62,20 @@ def getLastError(): @rtype: string """ -def imageToArray(image): +def imageToArray(image,mode): """ - Returns a string corresponding to the current image stored in a texture source object + Returns a BGL.buffer corresponding to the current image stored in a texture source object @param image: Image source object. @type image: object of type L{VideoFFmpeg}, L{ImageFFmpeg}, L{ImageBuff}, L{ImageMix}, L{ImageRender}, L{ImageMirror} or L{ImageViewport} - @rtype: string representing the image, 4 bytes per pixel in the RGBA order, line per line, starting from the bottom of the image. + @param mode: optional argument representing the pixel format. + You can use the characters R, G, B for the 3 color channels, A for the alpha channel, + 0 to force a fixed 0 color channel and 1 to force a fixed 255 color channel. + Example: "BGR" will return 3 bytes per pixel with the Blue, Green and Red channels in that order. + "RGB1" will return 4 bytes per pixel with the Red, Green, Blue channels in that order and the alpha channel forced to 255. + The default mode is "RGBA". + @type mode: string + @rtype: BGL.buffer object representing the image as one dimensional array of bytes of size (pixel_size*width*height), line by line starting from the bottom of the image. The pixel size and format is determined by the mode parameter. """ def materialID(object,name): """ @@ -80,7 +87,7 @@ def materialID(object,name): position of the texture stack. name can also have MA prefix if you want to identify the texture by material. In that case the material must have a texture channel in first position. - If the object has no material that matches name, it generates a runtime error. Use try/catch to catch the exception. + If the object has no material that matches name, it generates a runtime error. Use try/except to catch the exception. Ex: VideoTexture.materialID(obj, 'IMvideo.png') @@ -90,17 +97,22 @@ def materialID(object,name): @type name: string @rtype: integer """ -def setLogFile(): +def setLogFile(filename): """ - Does something - - @rtype: + Sets the name of a text file in which runtime error messages will be written, in addition to the printing + of the messages on the Python console. Only the runtime errors specific to the VideoTexture module + are written in that file, ordinary runtime time errors are not written. + + @param filename: name of error log file + @type filename: string + @rtype: integer """ def FilterBGR24(): """ - Does something + Returns a new input filter object to be used with L{ImageBuff} object when the image passed + to the ImageBuff.load() function has the 3-bytes pixel format BGR. - @rtype: + @rtype: object of type FilterBGR24 """ def FilterBlueScreen(): """ @@ -134,15 +146,17 @@ def FilterNormal(): """ def FilterRGB24(): """ - Does something + Returns a new input filter object to be used with L{ImageBuff} object when the image passed + to the ImageBuff.load() function has the 3-bytes pixel format RBG. - @rtype: + @rtype: object of type FilterRGB24 """ def FilterRGBA32(): """ - Does something + Returns a new input filter object to be used with L{ImageBuff} object when the image passed + to the ImageBuff.load() function has the 4-bytes pixel format RGBA. - @rtype: + @rtype: object of type FilterRGBA32 """ def ImageBuff(): """ diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.cpp b/source/gameengine/VideoTexture/VideoFFmpeg.cpp index 6f7e9b82911..290af8e63c5 100644 --- a/source/gameengine/VideoTexture/VideoFFmpeg.cpp +++ b/source/gameengine/VideoTexture/VideoFFmpeg.cpp @@ -56,7 +56,7 @@ m_frame(NULL), m_frameDeinterlaced(NULL), m_frameRGB(NULL), m_imgConvertCtx(NULL m_deinterlace(false), m_preseek(0), m_videoStream(-1), m_baseFrameRate(25.0), m_lastFrame(-1), m_eof(false), m_externTime(false), m_curPosition(-1), m_startTime(0), m_captWidth(0), m_captHeight(0), m_captRate(0.f), m_isImage(false), -m_isThreaded(false), m_stopThread(false), m_cacheStarted(false) +m_isThreaded(false), m_isStreaming(false), m_stopThread(false), m_cacheStarted(false) { // set video format m_format = RGB24; @@ -306,6 +306,7 @@ void *VideoFFmpeg::cacheThread(void *data) int frameFinished = 0; double timeBase = av_q2d(video->m_formatCtx->streams[video->m_videoStream]->time_base); int64_t startTs = video->m_formatCtx->streams[video->m_videoStream]->start_time; + if (startTs == AV_NOPTS_VALUE) startTs = 0; @@ -544,8 +545,10 @@ void VideoFFmpeg::openFile (char * filename) #endif ) { - // the file is in fact a streaming source, prevent seeking + // the file is in fact a streaming source, treat as cam to prevent seeking m_isFile = false; + // but it's not handled exactly like a camera. + m_isStreaming = true; // for streaming it is important to do non blocking read m_formatCtx->flags |= AVFMT_FLAG_NONBLOCK; } @@ -811,12 +814,12 @@ void VideoFFmpeg::calcImage (unsigned int texId, double ts) // close the file as we don't need it anymore release(); } - } else if (!m_isFile) + } else if (m_isStreaming) { // we didn't get a frame and we are streaming, this may be due to // a delay in the network or because we are getting the frame too fast. // In the later case, shift time by a small amount to compensate for a drift - m_startTime += 0.01; + m_startTime += 0.001; } } } @@ -878,14 +881,18 @@ AVFrame *VideoFFmpeg::grabFrame(long position) } // for streaming, always return the next frame, // that's what grabFrame does in non cache mode anyway. - if (!m_isFile || frame->framePosition == position) + if (m_isStreaming || frame->framePosition == position) { return frame->frame; } - if (frame->framePosition > position) + // for cam, skip old frames to keep image realtime. + // There should be no risk of clock drift since it all happens on the same CPU + if (frame->framePosition > position) + { // this can happen after rewind if the seek didn't find the first frame // the frame in the buffer is ahead of time, just leave it there return NULL; + } // this frame is not useful, release it pthread_mutex_lock(&m_cacheMutex); BLI_remlink(&m_frameCacheBase, frame); diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.h b/source/gameengine/VideoTexture/VideoFFmpeg.h index b9bf69039c7..a19d8969b40 100644 --- a/source/gameengine/VideoTexture/VideoFFmpeg.h +++ b/source/gameengine/VideoTexture/VideoFFmpeg.h @@ -61,7 +61,7 @@ static inline AVCodecContext* get_codec_from_stream(AVStream* stream) #include "VideoBase.h" -#define CACHE_FRAME_SIZE 5 +#define CACHE_FRAME_SIZE 10 #define CACHE_PACKET_SIZE 30 // type VideoFFmpeg declaration @@ -153,6 +153,9 @@ protected: /// is image loading done in a separate thread? bool m_isThreaded; + /// is streaming or camera? + bool m_isStreaming; + /// keep last image name STR_String m_imageName; |