diff options
author | Ton Roosendaal <ton@blender.org> | 2006-06-12 18:39:08 +0400 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2006-06-12 18:39:08 +0400 |
commit | bad72cec611664dcb68776281efd436c793465f7 (patch) | |
tree | c0dc9e51743fed41976392c3601b5616bd74f8e8 /source | |
parent | b0a22902ec1b6586325a027358415f5bdcb828f9 (diff) |
New feature! (Well, replacement for the exisiting cumbersome "DispView")
Next to the "DispWindow" there are now two new choices:
- Display render output to Image Editor
- Display render output to Screen-sized Image Editor
Both options won't open a 2nd window anymore, which makes work quite more
smooth even, especially because 'focus' isn't lost. Further it fits in the
'single window UI' paradigm of Blender. Should have been done 10 years ago!
Lastly it might bypass issues with X11... having 2 windows with opengl
context is not always stable in Linux.
This option uses an identical trick as for the Compositor viewer, using an
Image block with a fixed name ("Render Result").
The flow, when invoking a Render, goes as follows:
- first it checks if there's an Image Editor visible displaying the "Render
Result", if so then it uses that area-window.
(Use this option for dual-monitor setups for example, a render will always
go to the same location then)
- else it checks if there's an Image Editor open in general, it then
assigns that window the "Render Result" Image.
- else: it searches for the largest Area in the screen, and turns that into
a temporal Image Editor showing render output.
After a render, an ESC will push back the former view, if the Area type has
changed.
Same rules apply for the "Full Screen" option. Here an ESC will always go
back to the regular Screen, and restore Area type if required.
While rendering, the queue for the renderwindow isn't handled yet, so you can
not zoom (nor get full redraws), as for the regular render window.
Existing conflicts:
- in FaceSelect mode, the Image editor enforces to display the face texture
after rendering again.
- when using an Image window for compositing, you'll lose the Viewer output
on a render.
Implementation note:
While rendering updates, nothing is drawn in frontbuffer anymore. That's
good news for b0rked OpenGL drivers (and faster). However, for the few
OpenGL cards that don't do a "swap copy" but a "swap exchange" you get
issues... has to be worked on. I'm afraid we have to drop frontbuffer
drawing altogether.
Other fixes:
- Hotkeys NumPad 1, 2, 4, 8 will set zoom levels (was half coded only?)
Use SHIFT to zoom out (smaller).
- Rendering Tile updates still had draw errors on edges of tiles, in OSA
only. (Caused by commit 4 days ago)
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 5 | ||||
-rw-r--r-- | source/blender/include/BIF_drawimage.h | 4 | ||||
-rw-r--r-- | source/blender/include/BIF_renderwin.h | 10 | ||||
-rw-r--r-- | source/blender/include/blendef.h | 4 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_space_types.h | 22 | ||||
-rw-r--r-- | source/blender/python/api2_2x/sceneRender.c | 4 | ||||
-rw-r--r-- | source/blender/render/intern/source/pipeline.c | 2 | ||||
-rw-r--r-- | source/blender/src/buttons_scene.c | 6 | ||||
-rw-r--r-- | source/blender/src/drawimage.c | 397 | ||||
-rw-r--r-- | source/blender/src/editscreen.c | 15 | ||||
-rw-r--r-- | source/blender/src/header_image.c | 22 | ||||
-rw-r--r-- | source/blender/src/renderwin.c | 146 | ||||
-rw-r--r-- | source/blender/src/space.c | 48 |
13 files changed, 549 insertions, 136 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index e53d4cb4ba8..c9a90d0dc02 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -1947,8 +1947,8 @@ static void lib_link_image(FileData *fd, Main *main) static void direct_link_image(FileData *fd, Image *ima) { - ima->ibuf= 0; - ima->anim= 0; + ima->ibuf= NULL; + ima->anim= NULL; memset(ima->mipmap, 0, sizeof(ima->mipmap)); ima->repbind= 0; ima->bindcode= 0; @@ -3303,6 +3303,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc) sima->cumap= newdataadr(fd, sima->cumap); if(sima->cumap) direct_link_curvemapping(fd, sima->cumap); + sima->info_str= NULL; } else if(sl->spacetype==SPACE_NODE) { SpaceNode *snode= (SpaceNode *)sl; diff --git a/source/blender/include/BIF_drawimage.h b/source/blender/include/BIF_drawimage.h index 0435522025b..a3b12b7bafd 100644 --- a/source/blender/include/BIF_drawimage.h +++ b/source/blender/include/BIF_drawimage.h @@ -35,6 +35,7 @@ struct ScrArea; struct SpaceImage; +struct Render; void do_imagebuts(unsigned short event); void calc_image_view(struct SpaceImage *sima, char mode); @@ -50,5 +51,8 @@ void uvco_to_areaco_noclip(float *vec, int *mval); void what_image(struct SpaceImage *sima); void image_preview_event(int event); +void imagewindow_render_callbacks(struct Render *re); +void imagewindow_toggle_render(void); + #endif diff --git a/source/blender/include/BIF_renderwin.h b/source/blender/include/BIF_renderwin.h index eeb48ad8c27..dad4f36412c 100644 --- a/source/blender/include/BIF_renderwin.h +++ b/source/blender/include/BIF_renderwin.h @@ -31,6 +31,7 @@ */ struct ScrArea; +struct RenderStats; void calc_renderwin_rectangle(int rectx, int recty, int posmask, int renderpos_r[2], int rendersize_r[2]); @@ -50,3 +51,12 @@ void BIF_redraw_render_rect(void); void BIF_swap_render_rects(void); void BIF_toggle_render_display(void); +/* should not be here, ~WIP~ */ +void make_renderinfo_string(struct RenderStats *rs, char *str); + +/* space for info text */ +#define RW_HEADERY 18 + +/* header print for window */ +#define RW_MAXTEXT 512 + diff --git a/source/blender/include/blendef.h b/source/blender/include/blendef.h index 425d95cc112..0b2ca31a579 100644 --- a/source/blender/include/blendef.h +++ b/source/blender/include/blendef.h @@ -404,9 +404,9 @@ #define B_MESH_X_MIRROR 0x100 /* DISPLAYMODE */ -#define R_DISPLAYVIEW 0 +#define R_DISPLAYIMAGE 0 #define R_DISPLAYWIN 1 -#define R_DISPLAYAUTO 2 +#define R_DISPLAYSCREEN 2 /* Gvp.flag and Gwp.flag */ #define VP_COLINDEX 1 diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 946f40eafa6..14fc8a928ac 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -223,11 +223,17 @@ typedef struct SpaceImage { struct Image *image; struct CurveMapping *cumap; - float zoom; short mode, menunr; short imanr, curtile; - float xof, yof; - short flag, lock; + int flag; + short pad1, lock; + + float zoom, pad2; + + float xof, yof; /* user defined offset, image is centered */ + + float centx, centy; /* storage for offset while render drawing */ + char *info_str; /* info string for render */ } SpaceImage; typedef struct SpaceNla{ @@ -469,10 +475,12 @@ typedef struct SpaceImaSel { #define SI_COORDFLOATS 512 #define SI_PIXELSNAP 1024 #define SI_LIVE_UNWRAP 2048 -#define SI_USE_ALPHA 4096 -#define SI_SHOW_ALPHA 8192 -#define SI_SHOW_ZBUF 16384 - +#define SI_USE_ALPHA 0x1000 +#define SI_SHOW_ALPHA 0x2000 +#define SI_SHOW_ZBUF 0x4000 + /* next two for render window dislay */ +#define SI_PREVSPACE 0x8000 +#define SI_FULLWINDOW 0x10000 /* SpaceText flags (moved from DNA_text_types.h) */ diff --git a/source/blender/python/api2_2x/sceneRender.c b/source/blender/python/api2_2x/sceneRender.c index 8387b2a8d08..99b923d4eb4 100644 --- a/source/blender/python/api2_2x/sceneRender.c +++ b/source/blender/python/api2_2x/sceneRender.c @@ -351,7 +351,7 @@ PyObject *M_Render_SetRenderWinPos( PyObject * self, PyObject * args ) PyObject *M_Render_EnableDispView( PyObject * self ) { - G.displaymode = R_DISPLAYVIEW; + G.displaymode = R_DISPLAYIMAGE; EXPP_allqueue( REDRAWBUTSSCENE, 0 ); return EXPP_incr_ret( Py_None ); @@ -1850,7 +1850,7 @@ static int RenderData_setDisplayMode( BPy_RenderData *self, PyObject *value ) { return EXPP_setIValueRange( value, &G.displaymode, - R_DISPLAYVIEW, R_DISPLAYWIN, 'h' ); + R_DISPLAYIMAGE, R_DISPLAYWIN, 'h' ); } static PyObject *RenderData_getRenderPath( BPy_RenderData * self ) diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 8b34970309b..57c815878ae 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -367,7 +367,7 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop, int rr= MEM_callocT(sizeof(RenderResult), "new render result"); rr->rectx= rectx; rr->recty= recty; - rr->renrect.xmin= 0; rr->renrect.xmax= rectx; + rr->renrect.xmin= 0; rr->renrect.xmax= rectx-2*crop; /* crop is one or two extra pixels rendered for filtering, is used for merging and display too */ rr->crop= crop; diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c index ca061acdd33..c2f5f84199b 100644 --- a/source/blender/src/buttons_scene.c +++ b/source/blender/src/buttons_scene.c @@ -1216,10 +1216,8 @@ static void render_panel_output(void) uiDefButBitS(block, TOG, R_EXR_TILE_FILE, B_NOP, "Save Buffers", 72, 31, 120, 19, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Save the tiles for all RenderLayers and used SceneNodes to files, to save memory"); - uiBlockBeginAlign(block); - uiDefButS(block, ROW, B_REDR, "DispWin", 72, 10, 60, 20, &G.displaymode, 0.0, (float)R_DISPLAYWIN, 0, 0, "Sets render output to display in a separate window"); - uiDefButS(block, ROW, B_REDR, "DispView", 134, 10, 60, 20, &G.displaymode, 0.0, (float)R_DISPLAYVIEW, 0, 0, "Sets render output to display in 3D view"); - uiBlockEndAlign(block); + uiDefButS(block, MENU, B_REDR, "Render Display %t|Render Window %x1|Image Editor %x0|Full Screen %x2", + 72, 10, 120, 19, &G.displaymode, 0.0, (float)R_DISPLAYWIN, 0, 0, "Sets render output display"); uiDefButBitS(block, TOG, R_EXTENSION, B_NOP, "Extensions", 205, 10, 105, 19, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Adds extensions to the output when rendering animations"); diff --git a/source/blender/src/drawimage.c b/source/blender/src/drawimage.c index ede7210df3f..d67a0bc7931 100644 --- a/source/blender/src/drawimage.c +++ b/source/blender/src/drawimage.c @@ -87,6 +87,7 @@ #include "BIF_interface_icons.h" #include "BIF_editsima.h" #include "BIF_glutil.h" +#include "BIF_renderwin.h" #include "BIF_space.h" #include "BIF_screen.h" #include "BIF_transform.h" @@ -96,6 +97,9 @@ #include "BSE_trans_types.h" #include "BSE_view.h" +#include "RE_pipeline.h" +#include "BMF_Api.h" + /* Modules used */ #include "mydevice.h" #include "blendef.h" @@ -187,9 +191,16 @@ void calc_image_view(SpaceImage *sima, char mode) float zoom; if(image_preview_active(curarea, &xim, &yim)); - else if(sima->image && sima->image->ibuf) { - xim= sima->image->ibuf->x; - yim= sima->image->ibuf->y; + else if(sima->image) { + if(sima->image->ibuf) { + xim= sima->image->ibuf->x; + yim= sima->image->ibuf->y; + } + else if( strcmp(sima->image->name, "Render Result")==0 ) { + /* not very important, just nice */ + xim= (G.scene->r.xsch*G.scene->r.size)/100; + yim= (G.scene->r.ysch*G.scene->r.size)/100; + } } sima->v2d.tot.xmin= 0; @@ -229,21 +240,23 @@ void calc_image_view(SpaceImage *sima, char mode) } } +/* check for facelesect, and set active image */ void what_image(SpaceImage *sima) { TFace *activetf; Mesh *me; if(sima->mode==SI_TEXTURE) { - if(G.f & G_FACESELECT) { - + + if((G.f & G_FACESELECT) && G.rendering==0) { + sima->image= 0; me= get_mesh(OBACT); activetf = get_active_tface(); if(me && me->tface && activetf && activetf->mode & TF_TEX) { sima->image= activetf->tpage; - + if(sima->flag & SI_EDITTILE); else sima->curtile= activetf->tile; @@ -254,6 +267,24 @@ void what_image(SpaceImage *sima) } } } + else if(sima->image && strcmp(sima->image->name, "Render Result")==0) { + RenderResult rres; + /* make ibuf if needed, and initialize it */ + + /* allocate for each redraw, we don't want render result pointers hanging around */ + IMB_freeImBuf(sima->image->ibuf); + sima->image->ibuf= NULL; + + RE_GetResultImage(RE_GetRender(G.scene->id.name), &rres); + if(rres.rectf || rres.rect32) { + ImBuf *ibuf= sima->image->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, 0, 0); + + ibuf->x= rres.rectx; + ibuf->y= rres.recty; + ibuf->rect= rres.rect32; + ibuf->rect_float= rres.rectf; + } + } } } @@ -1175,6 +1206,12 @@ static void imagespace_grid(SpaceImage *sima) gridsize= sima->zoom; + calc_image_view(sima, 'f'); + myortho2(sima->v2d.cur.xmin, sima->v2d.cur.xmax, sima->v2d.cur.ymin, sima->v2d.cur.ymax); + + BIF_ThemeColorShade(TH_BACK, 20); + glRectf(0.0, 0.0, 1.0, 1.0); + if(gridsize<=0.0f) return; if(gridsize<1.0f) { @@ -1349,14 +1386,38 @@ static void sima_draw_zbuffloat_pixels(float x1, float y1, int rectx, int recty, MEM_freeN(rectf); } +static void imagewindow_draw_renderinfo(ScrArea *sa) +{ + SpaceImage *sima= sa->spacedata.first; + rcti rect; + float colf[3]; + + if(sima->info_str==NULL) + return; + + rect= sa->winrct; + rect.ymin= rect.ymax-RW_HEADERY; + + glaDefine2DArea(&rect); + + /* clear header rect */ + BIF_GetThemeColor3fv(TH_BACK, colf); + glClearColor(colf[0], colf[1], colf[2], 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + BIF_ThemeColor(TH_TEXT_HI); + glRasterPos2i(12, 5); + BMF_DrawString(G.fonts, sima->info_str); +} + void drawimagespace(ScrArea *sa, void *spacedata) { SpaceImage *sima= spacedata; ImBuf *ibuf= NULL; float col[3]; unsigned int *rect; - int x1, y1; - short sx, sy, dx, dy; + float x1, y1; + short sx, sy, dx, dy, show_render= 0; /* If derived data is used then make sure that object * is up-to-date... might not be the case because updates @@ -1374,29 +1435,30 @@ void drawimagespace(ScrArea *sa, void *spacedata) bwin_clear_viewmat(sa->win); /* clear buttons view */ glLoadIdentity(); + if(sima->image && strcmp(sima->image->name, "Render Result")==0 ) + show_render= 1; + what_image(sima); if(sima->image) { if(sima->image->ibuf==NULL) { load_image(sima->image, IB_rect, G.sce, G.scene->r.cfra); scrarea_queue_headredraw(sa); /* update header for image options */ - } + } + tag_image_time(sima->image); ibuf= sima->image->ibuf; } if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) { - calc_image_view(sima, 'f'); - myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax); - BIF_ThemeColorShade(TH_BACK, 20); - glRectf(0.0, 0.0, 1.0, 1.0); imagespace_grid(sima); - draw_tfaces(); + if(show_render==0) + draw_tfaces(); } else { float xim, yim, xoffs=0.0f, yoffs= 0.0f; - if(image_preview_active(curarea, &xim, &yim)) { + if(image_preview_active(sa, &xim, &yim)) { xoffs= G.scene->r.disprect.xmin; yoffs= G.scene->r.disprect.ymin; glColor3ub(0,0,0); @@ -1410,14 +1472,23 @@ void drawimagespace(ScrArea *sa, void *spacedata) } /* calc location */ - x1= sima->zoom*xoffs + (curarea->winx-sima->zoom*xim)/2; - y1= sima->zoom*yoffs + (curarea->winy-sima->zoom*yim)/2; + x1= sima->zoom*xoffs + ((float)sa->winx - sima->zoom*(float)xim)/2.0f; + y1= sima->zoom*yoffs + ((float)sa->winy - sima->zoom*(float)yim)/2.0f; x1-= sima->zoom*sima->xof; y1-= sima->zoom*sima->yof; /* needed for gla draw */ - glaDefine2DArea(&curarea->winrct); + if(show_render) { + rcti rct= sa->winrct; + + imagewindow_draw_renderinfo(sa); /* calls glaDefine2DArea too */ + + rct.ymax-=RW_HEADERY; + glaDefine2DArea(&rct); + } + else glaDefine2DArea(&sa->winrct); + glPixelZoom((float)sima->zoom, (float)sima->zoom); if(sima->flag & SI_EDITTILE) { @@ -1474,7 +1545,6 @@ void drawimagespace(ScrArea *sa, void *spacedata) } else { /* this part is generic image display */ - if(sima->flag & SI_SHOW_ALPHA) { if(ibuf->rect) sima_draw_alpha_pixels(x1, y1, ibuf->x, ibuf->y, ibuf->rect); @@ -1540,9 +1610,12 @@ void drawimagespace(ScrArea *sa, void *spacedata) glPixelZoom(1.0, 1.0); - draw_tfaces(); + if(show_render==0) + draw_tfaces(); } - + + glPixelZoom(1.0, 1.0); + calc_image_view(sima, 'f'); /* float */ } @@ -1551,15 +1624,18 @@ void drawimagespace(ScrArea *sa, void *spacedata) mywinset(sa->win); /* restore scissor after gla call... */ myortho2(-0.375, sa->winx-0.375, -0.375, sa->winy-0.375); - draw_image_view_tool(); - draw_image_view_icon(); + if(show_render==0) { + draw_image_view_tool(); + draw_image_view_icon(); + } draw_area_emboss(sa); /* it is important to end a view in a transform compatible with buttons */ bwin_scalematrix(sa->win, sima->blockscale, sima->blockscale, sima->blockscale); - image_blockhandlers(sa); + if(!(G.rendering && show_render)) + image_blockhandlers(sa); - curarea->win_swap= WIN_BACK_OK; + sa->win_swap= WIN_BACK_OK; } static void image_zoom_power_of_two(void) @@ -1673,6 +1749,10 @@ void image_viewzoom(unsigned short event, int invert) else if(event==PAD8) sima->zoom= (invert)? 8.0: 0.125; + /* ensure pixel exact locations for draw */ + sima->xof= (int)sima->xof; + sima->yof= (int)sima->yof; + if(image_preview_active(curarea, NULL, NULL)) { /* recalculates new preview rect */ scrarea_do_windraw(curarea); @@ -1695,7 +1775,7 @@ void image_home(void) if (curarea->spacetype != SPACE_IMAGE) return; - if ((G.sima->image == 0) || (G.sima->image->ibuf == 0)) { + if ((G.sima->image == NULL) || (G.sima->image->ibuf == NULL)) { imgwidth = 256; imgheight = 256; } @@ -1717,10 +1797,10 @@ void image_home(void) image_zoom_power_of_two(); } else { - G.sima->zoom= (float)1; + G.sima->zoom= 1.0f; } - G.sima->xof= G.sima->yof= 0; + G.sima->xof= G.sima->yof= 0.0f; calc_image_view(G.sima, 'p'); @@ -1740,8 +1820,8 @@ void image_viewcentre(void) yim= G.sima->image->ibuf->y; } - G.sima->xof= ((min[0] + max[0])*0.5f - 0.5f)*xim; - G.sima->yof= ((min[1] + max[1])*0.5f - 0.5f)*yim; + G.sima->xof= (int) (((min[0] + max[0])*0.5f - 0.5f)*xim); + G.sima->yof= (int) (((min[1] + max[1])*0.5f - 0.5f)*yim); d[0] = max[0] - min[0]; d[1] = max[1] - min[1]; @@ -1756,3 +1836,260 @@ void image_viewcentre(void) scrarea_queue_winredraw(curarea); } + +/* *********************** render callbacks ***************** */ + +/* set on initialize render, only one render output to imagewindow can exist, so the global isnt dangerous yet :) */ +static ScrArea *image_area= NULL; + +/* can get as well the full picture, as the parts while rendering */ +static void imagewindow_progress(ScrArea *sa, RenderResult *rr, volatile rcti *renrect) +{ + SpaceImage *sima= sa->spacedata.first; + float x1, y1, *rectf= NULL; + unsigned int *rect32= NULL; + int ymin, ymax, xmin, xmax; + + /* if renrect argument, we only display scanlines */ + if(renrect) { + /* if ymax==recty, rendering of layer is ready, we should not draw, other things happen... */ + if(rr->renlay==NULL || renrect->ymax>=rr->recty) + return; + + /* xmin here is first subrect x coord, xmax defines subrect width */ + xmin = renrect->xmin; + xmax = renrect->xmax - xmin; + if (xmax<2) return; + + ymin= renrect->ymin; + ymax= renrect->ymax - ymin; + if(ymax<2) + return; + renrect->ymin= renrect->ymax; + } + else { + xmin = ymin = 0; + xmax = rr->rectx - 2*rr->crop; + ymax = rr->recty - 2*rr->crop; + } + + /* image window cruft */ + + /* find current float rect for display, first case is after composit... still weak */ + if(rr->rectf) + rectf= rr->rectf; + else { + if(rr->rect32) + rect32= rr->rect32; + else { + if(rr->renlay==NULL || rr->renlay->rectf==NULL) return; + rectf= rr->renlay->rectf; + } + } + if(rectf) { + /* if scanline updates... */ + rectf+= 4*(rr->rectx*ymin + xmin); + + /* when rendering more pixels than needed, we crop away cruft */ + if(rr->crop) + rectf+= 4*(rr->crop*rr->rectx + rr->crop); + } + + /* tilerect defines drawing offset from (0,0) */ + /* however, tilerect (xmin, ymin) is first pixel */ + x1 = sima->centx + (rr->tilerect.xmin + rr->crop + xmin)*sima->zoom; + y1 = sima->centy + (rr->tilerect.ymin + rr->crop + ymin)*sima->zoom; + + /* needed for gla draw */ + { rcti rct= sa->winrct; rct.ymax-= RW_HEADERY; glaDefine2DArea(&rct);} + + glPixelZoom((float)sima->zoom, (float)sima->zoom); + + if(rect32) + glaDrawPixelsSafe(x1, y1, xmax, ymax, rr->rectx, GL_RGBA, GL_UNSIGNED_BYTE, rect32); + else + glaDrawPixelsSafe(x1, y1, xmax, ymax, rr->rectx, GL_RGBA, GL_FLOAT, rectf); + + glPixelZoom(1.0, 1.0); + +} + + +/* in render window; display a couple of scanlines of rendered image */ +static void imagewindow_progress_display_cb(RenderResult *rr, volatile rcti *rect) +{ + + if (image_area) { + imagewindow_progress(image_area, rr, rect); + image_area->win_swap= WIN_BACK_OK; + screen_swapbuffers(); + } +} + +/* unused, init_display_cb is called on each render */ +static void imagewindow_clear_display_cb(RenderResult *rr) +{ + if (image_area) { + } +} + +static ScrArea *biggest_area(void) +{ + ScrArea *sa, *big= NULL; + int size, maxsize= 0; + + for(sa= G.curscreen->areabase.first; sa; sa= sa->next) { + size= sa->winx*sa->winy; + if(size > maxsize) { + maxsize= size; + big= sa; + } + } + return big; +} + + +/* if R_DISPLAYIMAGE + use Image Window showing Render Result + or: use largest Image Window + else: turn largest 3d view into Image Window + if R_DISPSCREEN + make a new temp fullscreen area with Image Window +*/ + +static ScrArea *imagewindow_set_render_display(void) +{ + ScrArea *sa; + SpaceImage *sima; + + /* find an imagewindow showing render result */ + for(sa=G.curscreen->areabase.first; sa; sa= sa->next) { + if(sa->spacetype==SPACE_IMAGE) { + sima= sa->spacedata.first; + + if(sima->image && strcmp(sima->image->name, "Render Result")==0 ) + break; + } + } + if(sa==NULL) { + /* find an open image window */ + for(sa=G.curscreen->areabase.first; sa; sa= sa->next) + if(sa->spacetype==SPACE_IMAGE) + break; + + if(sa==NULL) { + + /* find largest open area */ + sa= biggest_area(); + newspace(sa, SPACE_IMAGE); + sima= sa->spacedata.first; + + /* makes ESC go back to prev space */ + sima->flag |= SI_PREVSPACE; + } + } + + sima= sa->spacedata.first; + + /* get the correct image, and scale it */ + sima->image = (Image *)find_id("IM", "Render Result"); + + if(sima->image==NULL) { + Image *ima= alloc_libblock(&G.main->image, ID_IM, "Render Result"); + strcpy(ima->name, "Render Result"); + ima->ok= 1; + ima->xrep= ima->yrep= 1; + sima->image= ima; + } + + if(G.displaymode==R_DISPLAYSCREEN) { + if(sa->full==0) { + sima->flag |= SI_FULLWINDOW; + /* fullscreen works with lousy curarea */ + curarea= sa; + area_fullscreen(); + sa= curarea; + } + } + + return sa; +} + +static void imagewindow_init_display_cb(RenderResult *rr) +{ + + image_area= imagewindow_set_render_display(); + + if(image_area) { + SpaceImage *sima= image_area->spacedata.first; + + areawinset(image_area->win); + + /* calc location using original size (tiles don't tell) */ + sima->centx= (image_area->winx - sima->zoom*(float)rr->rectx)/2.0f; + sima->centy= (image_area->winy - sima->zoom*(float)rr->recty)/2.0f; + + sima->centx-= sima->zoom*sima->xof; + sima->centy-= sima->zoom*sima->yof; + + drawimagespace(image_area, sima); + if(image_area->headertype) scrarea_do_headdraw(image_area); + screen_swapbuffers(); + + allqueue(REDRAWIMAGE, 0); /* redraw in end */ + } +} + +/* coming from BIF_toggle_render_display() */ +void imagewindow_toggle_render(void) +{ + ScrArea *sa; + + /* check if any imagewindow is showing temporal render output */ + for(sa=G.curscreen->areabase.first; sa; sa= sa->next) { + if(sa->spacetype==SPACE_IMAGE) { + SpaceImage *sima= sa->spacedata.first; + + if(sima->image && strcmp(sima->image->name, "Render Result")==0 ) + if(sima->flag & (SI_PREVSPACE|SI_FULLWINDOW)) + break; + } + } + if(sa) { + addqueue(sa->win, ESCKEY, 1); /* also returns from fullscreen */ + } + else { + sa= imagewindow_set_render_display(); + scrarea_queue_headredraw(sa); + scrarea_queue_winredraw(sa); + } +} + +static void imagewindow_renderinfo_cb(RenderStats *rs) +{ + + if(image_area) { + SpaceImage *sima= image_area->spacedata.first; + + if(sima->info_str==NULL) + sima->info_str= MEM_callocN(RW_MAXTEXT, "info str imagewin"); + + if(rs) + make_renderinfo_string(rs, sima->info_str); + + imagewindow_draw_renderinfo(image_area); + + image_area->win_swap= WIN_BACK_OK; + screen_swapbuffers(); + } +} + + +void imagewindow_render_callbacks(Render *re) +{ + RE_display_init_cb(re, imagewindow_init_display_cb); + RE_display_draw_cb(re, imagewindow_progress_display_cb); + RE_display_clear_cb(re, imagewindow_clear_display_cb); + RE_stats_draw_cb(re, imagewindow_renderinfo_cb); +} + diff --git a/source/blender/src/editscreen.c b/source/blender/src/editscreen.c index a1891bd3182..2af0e5de3d5 100644 --- a/source/blender/src/editscreen.c +++ b/source/blender/src/editscreen.c @@ -180,8 +180,10 @@ static int choose_cursor(ScrArea *sa) void wich_cursor(ScrArea *sa) { sa->cursor= choose_cursor(sa); - - screen_set_cursor(G.curscreen); + + /* well... the waitcursor() is not a state, so this call will cancel it out */ + if(get_cursor()!=CURSOR_WAIT) + screen_set_cursor(G.curscreen); } @@ -2215,7 +2217,12 @@ void setscreen(bScreen *sc) for(sa= sc->areabase.first; sa; sa= sa->next) { SpaceLink *sl; - + + /* there's also events in queue for this, but we call fullscreen for render output + now, and that doesn't go back to queue. Bad code, but doesn't hurt... (ton) */ + scrarea_do_headchange(sa); + scrarea_do_winchange(sa); + for(sl= sa->spacedata.first; sl; sl= sl->next) { sl->area= sa; @@ -3673,7 +3680,7 @@ int get_cursor(void) { } void set_cursor(int curs) { - if (!(G.rendering) && G.background == 0) { + if (G.background == 0) { if (curs!=curcursor) { curcursor= curs; window_set_cursor(mainwin, curs); diff --git a/source/blender/src/header_image.c b/source/blender/src/header_image.c index 324b3ba0cd4..ede2b6d51d6 100644 --- a/source/blender/src/header_image.c +++ b/source/blender/src/header_image.c @@ -407,13 +407,13 @@ static uiBlock *image_view_viewnavmenu(void *arg_unused) uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom 1:8", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom 1:4", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom 1:2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom 1:1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom 2:1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom 4:1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom 8:1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 9, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom 1:8|Shift+NumPad 8", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom 1:4|Shift+NumPad 4", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom 1:2|Shift+NumPad 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom 1:1|NumPad 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom 2:1|NumPad 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom 4:1|NumPad 4", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom 8:1|NumPad 8", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 9, ""); uiBlockSetDirection(block, UI_RIGHT); uiTextBoundsBlock(block, 50); @@ -1198,17 +1198,17 @@ void image_buttons(void) uiDefIconButBitI(block, TOG, 1, B_SIMAPACKIMA, ICON_PACKAGE, xco,0,XIC,YIC, &headerbuttons_packdummy, 0, 0, 0, 0, "Pack/Unpack this image"); xco+= XIC+8; - uiDefIconButBitS(block, TOG, SI_DRAWTOOL, B_SIMAGEPAINTTOOL, ICON_TPAINT_HLT, xco,0,XIC,YIC, &G.sima->flag, 0, 0, 0, 0, "Enables painting textures on the image with left mouse button"); + uiDefIconButBitI(block, TOG, SI_DRAWTOOL, B_SIMAGEPAINTTOOL, ICON_TPAINT_HLT, xco,0,XIC,YIC, &G.sima->flag, 0, 0, 0, 0, "Enables painting textures on the image with left mouse button"); xco+= XIC+8; uiBlockBeginAlign(block); - uiDefIconButBitS(block, TOG, SI_USE_ALPHA, B_SIMA_USE_ALPHA, ICON_TRANSP_HLT, xco,0,XIC,YIC, &G.sima->flag, 0, 0, 0, 0, "Draws image with alpha"); + uiDefIconButBitI(block, TOG, SI_USE_ALPHA, B_SIMA_USE_ALPHA, ICON_TRANSP_HLT, xco,0,XIC,YIC, &G.sima->flag, 0, 0, 0, 0, "Draws image with alpha"); xco+= XIC; - uiDefIconButBitS(block, TOG, SI_SHOW_ALPHA, B_SIMA_SHOW_ALPHA, ICON_DOT, xco,0,XIC,YIC, &G.sima->flag, 0, 0, 0, 0, "Draws only alpha"); + uiDefIconButBitI(block, TOG, SI_SHOW_ALPHA, B_SIMA_SHOW_ALPHA, ICON_DOT, xco,0,XIC,YIC, &G.sima->flag, 0, 0, 0, 0, "Draws only alpha"); xco+= XIC; if(G.sima->image->ibuf) { if(G.sima->image->ibuf->zbuf || G.sima->image->ibuf->zbuf_float) { - uiDefIconButBitS(block, TOG, SI_SHOW_ZBUF, B_SIMA_SHOW_ZBUF, ICON_SOLID, xco,0,XIC,YIC, &G.sima->flag, 0, 0, 0, 0, "Draws zbuffer values"); + uiDefIconButBitI(block, TOG, SI_SHOW_ZBUF, B_SIMA_SHOW_ZBUF, ICON_SOLID, xco,0,XIC,YIC, &G.sima->flag, 0, 0, 0, 0, "Draws zbuffer values"); xco+= XIC; } else G.sima->flag &= ~SI_SHOW_ZBUF; /* no confusing display for non-zbuf images */ diff --git a/source/blender/src/renderwin.c b/source/blender/src/renderwin.c index 4a93afd6137..26a232f7a5d 100644 --- a/source/blender/src/renderwin.c +++ b/source/blender/src/renderwin.c @@ -73,6 +73,7 @@ #include "BKE_utildefines.h" #include "BKE_writeavi.h" /* movie handle */ +#include "BIF_drawimage.h" #include "BIF_gl.h" #include "BIF_glutil.h" #include "BIF_graphics.h" @@ -126,11 +127,6 @@ /* forces draw of alpha */ #define RW_FLAGS_ALPHA (1<<4) -/* space for info text */ -#define RW_HEADERY 18 - -/* header print for window */ -#define RW_MAXTEXT 512 typedef struct { Window *win; @@ -889,38 +885,66 @@ static void renderwin_progress_display_cb(RenderResult *rr, volatile rcti *rect) /* -------------- callbacks for render loop: interactivity ----------------------- */ - -/* callback for print info in top header of renderwin */ -static void printrenderinfo_cb(RenderStats *rs) +/* string is RW_MAXTEXT chars min */ +void make_renderinfo_string(RenderStats *rs, char *str) { extern char info_time_str[32]; // header_info.c extern unsigned long mem_in_use, mmap_in_use; static float megs_used_memory, mmap_used_memory; - char *spos= render_win->render_text; - + char *spos= str; + megs_used_memory= (mem_in_use-mmap_in_use)/(1024.0*1024.0); mmap_used_memory= (mmap_in_use)/(1024.0*1024.0); - if(render_win) { - if(G.scene->lay & 0xFF000000) - spos+= sprintf(spos, "Localview | "); - else if(G.scene->r.scemode & R_SINGLE_LAYER) - spos+= sprintf(spos, "Single Layer | "); + if(G.scene->lay & 0xFF000000) + spos+= sprintf(spos, "Localview | "); + else if(G.scene->r.scemode & R_SINGLE_LAYER) + spos+= sprintf(spos, "Single Layer | "); + + if(rs->tothalo) + spos+= sprintf(spos, "Fra:%d Ve:%d Fa:%d Ha:%d La:%d Mem:%.2fM (%.2fM)", (G.scene->r.cfra), rs->totvert, rs->totface, rs->tothalo, rs->totlamp, megs_used_memory, mmap_used_memory); + else + spos+= sprintf(spos, "Fra:%d Ve:%d Fa:%d La:%d Mem:%.2fM (%.2fM)", (G.scene->r.cfra), rs->totvert, rs->totface, rs->totlamp, megs_used_memory, mmap_used_memory); + + BLI_timestr(rs->lastframetime, info_time_str); + spos+= sprintf(spos, " Time:%s ", info_time_str); + + if(rs->infostr) + spos+= sprintf(spos, " | %s", rs->infostr); + + /* very weak... but 512 characters is quite safe... we cannot malloc during thread render */ + if(spos >= str+RW_MAXTEXT) + printf("WARNING! renderwin text beyond limit \n"); + + /* temporal render debug printing, needed for testing orange renders atm... will be gone soon (or option) */ + if(G.rt==7 && rs->convertdone) { + char str[256]; - if(rs->tothalo) - spos+= sprintf(spos, "Fra:%d Ve:%d Fa:%d Ha:%d La:%d Mem:%.2fM (%.2fM)", (G.scene->r.cfra), rs->totvert, rs->totface, rs->tothalo, rs->totlamp, megs_used_memory, mmap_used_memory); - else - spos+= sprintf(spos, "Fra:%d Ve:%d Fa:%d La:%d Mem:%.2fM (%.2fM)", (G.scene->r.cfra), rs->totvert, rs->totface, rs->totlamp, megs_used_memory, mmap_used_memory); - - BLI_timestr(rs->lastframetime, info_time_str); - spos+= sprintf(spos, " Time:%s ", info_time_str); + spos= str; + spos+= sprintf(spos, "Fra:%d Mem:%.2fM (%.2fM)", G.scene->r.cfra, megs_used_memory, mmap_used_memory); - if(rs->infostr) + if(rs->infostr) { spos+= sprintf(spos, " | %s", rs->infostr); + } + else { + if(rs->tothalo) + spos+= sprintf(spos, "Sce: %s Ve:%d Fa:%d Ha:%d La:%d", G.scene->id.name+2, rs->totvert, rs->totface, rs->tothalo, rs->totlamp); + else + spos+= sprintf(spos, "Sce: %s Ve:%d Fa:%d La:%d", G.scene->id.name+2, rs->totvert, rs->totface, rs->totlamp); + } + printf(str); printf("\n"); + } + + +} + +/* callback for print info in top header of renderwin */ +static void renderwin_renderinfo_cb(RenderStats *rs) +{ + + if(render_win) { - /* very weak... but 512 characters is quite safe... we cannot malloc during thread render */ - if(spos >= render_win->render_text+RW_MAXTEXT) - printf("WARNING! renderwin text beyond limit \n"); + make_renderinfo_string(rs, render_win->render_text); #ifdef __APPLE__ #else @@ -937,24 +961,6 @@ static void printrenderinfo_cb(RenderStats *rs) #endif } - /* temporal render debug printing, needed for testing orange renders atm... will be gone soon (or option) */ - if(G.rt==7 && rs->convertdone) { - char str[256]; - spos= str; - spos+= sprintf(spos, "Fra:%d Mem:%.2fM (%.2fM)", G.scene->r.cfra, megs_used_memory, mmap_used_memory); - - if(rs->infostr) { - spos+= sprintf(spos, " | %s", rs->infostr); - } - else { - if(rs->tothalo) - spos+= sprintf(spos, "Sce: %s Ve:%d Fa:%d Ha:%d La:%d", G.scene->id.name+2, rs->totvert, rs->totface, rs->tothalo, rs->totlamp); - else - spos+= sprintf(spos, "Sce: %s Ve:%d Fa:%d La:%d", G.scene->id.name+2, rs->totvert, rs->totface, rs->totlamp); - } - printf(str); printf("\n"); - } - } /* -------------- callback system to allow ESC from rendering ----------------------- */ @@ -1086,17 +1092,26 @@ static void do_render(int anim) G.afbreek= 0; /* set callbacks */ - RE_display_init_cb(re, renderwin_init_display_cb); - RE_display_draw_cb(re, renderwin_progress_display_cb); - RE_display_clear_cb(re, renderwin_clear_display_cb); + if(G.displaymode!=R_DISPLAYWIN) { + if(render_win) + BIF_close_render_display(); + imagewindow_render_callbacks(re); + } + else { + RE_display_init_cb(re, renderwin_init_display_cb); + RE_display_draw_cb(re, renderwin_progress_display_cb); + RE_display_clear_cb(re, renderwin_clear_display_cb); + RE_stats_draw_cb(re, renderwin_renderinfo_cb); + } RE_error_cb(re, error_cb); init_test_break_callback(); RE_test_break_cb(re, test_break); RE_timecursor_cb(re, set_timecursor); - RE_stats_draw_cb(re, printrenderinfo_cb); - if(render_win) window_set_cursor(render_win->win, CURSOR_WAIT); - + waitcursor(1); + if(render_win) + window_set_cursor(render_win->win, CURSOR_WAIT); + if(G.obedit) exit_editmode(0); /* 0 = no free data */ @@ -1380,21 +1395,26 @@ void BIF_close_render_display(void) void BIF_toggle_render_display(void) { - if (render_win) { - if(render_win->active) { - mainwindow_raise(); - mainwindow_make_active(); - render_win->active= 0; - } + if (G.displaymode!=R_DISPLAYWIN) { + imagewindow_toggle_render(); + } + else { + if (render_win) { + if(render_win->active) { + mainwindow_raise(); + mainwindow_make_active(); + render_win->active= 0; + } + else { + window_raise(render_win->win); + window_make_active(render_win->win); + render_win->active= 1; + } + } else { - window_raise(render_win->win); - window_make_active(render_win->win); - render_win->active= 1; + RenderResult *rr= RE_GetResult(RE_GetRender(G.scene->id.name)); + if(rr) renderwin_init_display_cb(rr); } - } - else { - RenderResult *rr= RE_GetResult(RE_GetRender(G.scene->id.name)); - if(rr) renderwin_init_display_cb(rr); } } diff --git a/source/blender/src/space.c b/source/blender/src/space.c index 515e8d212ff..871cb27f37e 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -4041,13 +4041,13 @@ static void changeimagepace(ScrArea *sa, void *spacedata) static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt) { + SpaceImage *sima= spacedata; unsigned short event= evt->event, origevent= evt->event; short val= evt->val; - SpaceImage *sima= curarea->spacedata.first; if(val==0) return; - if(uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0; + if(uiDoBlocks(&sa->uiblocks, event)!=UI_NOTHING ) event= 0; if (U.flag & USER_LMOUSESELECT) { if (event == LEFTMOUSE) { @@ -4060,8 +4060,8 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt) if (sima->flag & SI_DRAWTOOL) { switch(event) { case CKEY: - toggle_blockhandler(curarea, IMAGE_HANDLER_PAINT, UI_PNL_UNSTOW); - scrarea_queue_winredraw(curarea); + toggle_blockhandler(sa, IMAGE_HANDLER_PAINT, UI_PNL_UNSTOW); + scrarea_queue_winredraw(sa); break; case LEFTMOUSE: imagepaint_paint(origevent==LEFTMOUSE? L_MOUSE: R_MOUSE); @@ -4167,8 +4167,8 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt) } else { if(G.qual==LR_SHIFTKEY) { - toggle_blockhandler(curarea, IMAGE_HANDLER_PREVIEW, 0); - scrarea_queue_winredraw(curarea); + toggle_blockhandler(sa, IMAGE_HANDLER_PREVIEW, 0); + scrarea_queue_winredraw(sa); } } break; @@ -4220,19 +4220,43 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt) image_viewmove(0); break; case WHEELUPMOUSE: case WHEELDOWNMOUSE: case PADPLUSKEY: case PADMINUS: - image_viewzoom(event, 0); - scrarea_queue_winredraw(curarea); + case PAD1: case PAD2: case PAD4: case PAD8: + image_viewzoom(event, (G.qual & LR_SHIFTKEY)==0); + scrarea_queue_winredraw(sa); break; case HOMEKEY: if((G.qual==0)) image_home(); + break; case NKEY: if(G.qual==0) { - toggle_blockhandler(curarea, IMAGE_HANDLER_PROPERTIES, UI_PNL_TO_MOUSE); - scrarea_queue_winredraw(curarea); + toggle_blockhandler(sa, IMAGE_HANDLER_PROPERTIES, UI_PNL_TO_MOUSE); + scrarea_queue_winredraw(sa); } break; + case ESCKEY: + if(sima->flag & SI_PREVSPACE) { + /* only allow ESC once */ + sima->flag &= ~SI_PREVSPACE; + + sima= sa->spacedata.first; + if(sima->next) { + SpaceLink *sl; + + BLI_remlink(&sa->spacedata, sima); + BLI_addtail(&sa->spacedata, sima); + + sl= sa->spacedata.first; + + newspace(sa, sl->spacetype); + } + } + if(sima->flag & SI_FULLWINDOW) { + sima->flag &= ~SI_FULLWINDOW; + if(sa->full) + area_fullscreen(); + } } } @@ -4869,6 +4893,8 @@ void freespacelist(ScrArea *sa) SpaceImage *sima= (SpaceImage *)sl; if(sima->cumap) curvemapping_free(sima->cumap); + if(sima->info_str) + MEM_freeN(sima->info_str); } else if(sl->spacetype==SPACE_NODE) { /* SpaceNode *snode= (SpaceNode *)sl; */ @@ -4940,6 +4966,8 @@ void duplicatespacelist(ScrArea *newarea, ListBase *lb1, ListBase *lb2) SpaceImage *sima= (SpaceImage *)sl; if(sima->cumap) sima->cumap= curvemapping_copy(sima->cumap); + if(sima->info_str) + sima->info_str= MEM_dupallocN(sima->info_str); } sl= sl->next; } |