Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2010-03-29 02:45:14 +0400
committerTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2010-03-29 02:45:14 +0400
commitf4e9c5d71e7de908384c713da52585e027abe49e (patch)
tree48e1dab2ae492a1e1aa0d3f7ae191a844b86adf0 /source
parente2cb63574485efb2a9ccde1f0b15a29d086dd194 (diff)
parent33ee3fc6fe0d387e1efb2b545cab441867fb1b48 (diff)
Merged changes in the trunk up to revision 27817.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenfont/intern/blf_font.c49
-rw-r--r--source/blender/blenkernel/BKE_image.h3
-rw-r--r--source/blender/blenkernel/intern/collision.c2
-rw-r--r--source/blender/blenkernel/intern/displist.c6
-rw-r--r--source/blender/blenkernel/intern/image.c95
-rw-r--r--source/blender/blenkernel/intern/modifier.c3
-rw-r--r--source/blender/blenkernel/intern/sequencer.c4
-rw-r--r--source/blender/blenkernel/intern/writeframeserver.c39
-rw-r--r--source/blender/blenloader/intern/readfile.c11
-rw-r--r--source/blender/blenloader/intern/writefile.c4
-rw-r--r--source/blender/editors/include/ED_view3d.h1
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c2
-rw-r--r--source/blender/editors/object/object_add.c40
-rw-r--r--source/blender/editors/object/object_bake.c2
-rw-r--r--source/blender/editors/render/render_internal.c45
-rw-r--r--source/blender/editors/render/render_opengl.c2
-rw-r--r--source/blender/editors/render/render_preview.c20
-rw-r--r--source/blender/editors/screen/screen_edit.c4
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c8
-rw-r--r--source/blender/editors/space_file/file_ops.c5
-rw-r--r--source/blender/editors/space_file/writeimage.c6
-rw-r--r--source/blender/editors/space_image/SConscript3
-rw-r--r--source/blender/editors/space_image/image_buttons.c24
-rw-r--r--source/blender/editors/space_image/image_draw.c77
-rw-r--r--source/blender/editors/space_image/image_ops.c18
-rw-r--r--source/blender/editors/space_node/node_edit.c2
-rw-r--r--source/blender/editors/space_view3d/drawvolume.c7
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c6
-rw-r--r--source/blender/editors/transform/transform.c5
-rw-r--r--source/blender/editors/transform/transform.h3
-rw-r--r--source/blender/editors/transform/transform_snap.c2
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp2
-rw-r--r--source/blender/gpu/intern/gpu_extensions.c3
-rw-r--r--source/blender/makesdna/DNA_image_types.h18
-rw-r--r--source/blender/makesrna/intern/rna_render.c10
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_composite.c2
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_image.c2
-rw-r--r--source/blender/python/doc/epy/BGL.py28
-rw-r--r--source/blender/python/generic/bgl.c7
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h32
-rw-r--r--source/blender/render/intern/source/convertblender.c2
-rw-r--r--source/blender/render/intern/source/envmap.c4
-rw-r--r--source/blender/render/intern/source/pipeline.c196
-rw-r--r--source/blender/render/intern/source/sss.c2
-rw-r--r--source/blender/windowmanager/intern/wm_window.c2
-rw-r--r--source/blenderplayer/bad_level_call_stubs/stubs.c4
-rw-r--r--source/creator/creator.c8
-rw-r--r--source/gameengine/Converter/BL_ArmatureObject.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.cpp7
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp20
-rw-r--r--source/gameengine/Ketsji/KX_Scene.h2
-rw-r--r--source/gameengine/PyDoc/GameTypes.py10
-rw-r--r--source/gameengine/PyDoc/VideoTexture.py48
-rw-r--r--source/gameengine/VideoTexture/VideoFFmpeg.cpp19
-rw-r--r--source/gameengine/VideoTexture/VideoFFmpeg.h5
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;