224
239
/* now calculate a zoom for when image is larger than window */
225
240
window_get_size(rw->win, &w, &h);
226
/* at this point the r.rectx/y values are not correct yet */
243
/* at this point the r.rectx/y values are not correct yet */
227
244
rectx= (G.scene->r.size*G.scene->r.xsch)/100;
228
245
recty= (G.scene->r.size*G.scene->r.ysch)/100;
247
/* crop option makes image smaller */
248
if ((G.scene->r.mode & R_BORDER) && (G.scene->r.mode & R_MOVIECROP)) {
249
if(!(G.scene->r.scemode & R_OGL)) {
250
rectx*= (G.scene->r.border.xmax-G.scene->r.border.xmin);
251
recty*= (G.scene->r.border.ymax-G.scene->r.border.ymin);
230
255
if(rectx>w || recty>h) {
231
256
if(rectx-w > recty-h) rw->zoom= ((float)w)/((float)rectx);
232
257
else rw->zoom= ((float)h)/((float)recty);
237
262
renderwin_queue_redraw(rw);
265
static void renderwin_draw_render_info(RenderWin *rw)
267
/* render text is added to top */
272
window_get_size(rw->win, &rect.xmax, &rect.ymax);
274
rect.ymin= rect.ymax-RW_HEADERY;
275
glEnable(GL_SCISSOR_TEST);
276
glaDefine2DArea(&rect);
278
/* clear header rect */
279
BIF_SetTheme(NULL); // sets view3d theme by default
280
BIF_GetThemeColor3fv(TH_HEADER, colf);
281
glClearColor(colf[0], colf[1], colf[2], 1.0);
282
glClear(GL_COLOR_BUFFER_BIT);
284
if(rw->render_text) {
285
BIF_ThemeColor(TH_TEXT);
286
glRasterPos2i(12, 5);
287
BMF_DrawString(G.fonts, rw->render_text);
240
293
static void renderwin_draw(RenderWin *rw, int just_clear)
242
295
float disprect[2][2];
296
int set_back_mainwindow;
299
/* since renderwin uses callbacks (controlled by ghost) it can
300
mess up active window output with redraw events after a render.
301
this is patchy, still WIP */
302
set_back_mainwindow = (winlay_get_active_window() != rw->win);
303
window_make_active(rw->win);
245
305
rect.xmin= rect.ymin= 0;
246
306
window_get_size(rw->win, &rect.xmax, &rect.ymax);
307
rect.ymax-= RW_HEADERY;
247
309
renderwin_get_disprect(rw, disprect);
249
window_make_active(rw->win);
311
/* do this first, so window ends with correct scissor */
312
renderwin_draw_render_info(rw);
251
314
glEnable(GL_SCISSOR_TEST);
252
315
glaDefine2DArea(&rect);
259
322
glRectfv(disprect[0], disprect[1]);
261
324
glPixelZoom(rw->zoom, rw->zoom);
262
glaDrawPixelsSafe(disprect[0][0], disprect[0][1], R.rectx, R.recty, R.rectot);
325
if(rw->flags & RW_FLAGS_ALPHA) {
326
char *rect= (char *)R.rectot;
328
glColorMask(1, 0, 0, 0);
329
glaDrawPixelsSafe(disprect[0][0], disprect[0][1], R.rectx, R.recty, rect+3);
330
glColorMask(0, 1, 0, 0);
331
glaDrawPixelsSafe(disprect[0][0], disprect[0][1], R.rectx, R.recty, rect+2);
332
glColorMask(0, 0, 1, 0);
333
glaDrawPixelsSafe(disprect[0][0], disprect[0][1], R.rectx, R.recty, rect+1);
334
glColorMask(1, 1, 1, 1);
338
glaDrawPixelsSafe(disprect[0][0], disprect[0][1], R.rectx, R.recty, R.rectot);
263
340
glPixelZoom(1.0, 1.0);
343
/* info text is overlayed on bottom */
266
344
if (rw->info_text) {
268
346
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
286
366
if (rw->flags & RW_FLAGS_PIXEL_EXAMINING) {
369
int *pxlz; // zbuffer is signed
290
372
if (R.rectot && renderwin_win_to_image_co(rw, rw->lmouse, imgco)) {
291
unsigned char *pxl= (char*) &R.rectot[R.rectx*imgco[1] + imgco[0]];
373
pxl= (char*) &R.rectot[R.rectx*imgco[1] + imgco[0]];
376
pxlz= &R.rectz[R.rectx*imgco[1] + imgco[0]];
377
sprintf(buf, "R: %d, G: %d, B: %d, A: %d, Z: %f", pxl[0], pxl[1], pxl[2], pxl[3], 0.5+0.5*( ((float)*pxlz)/(float)INT_MAX) );
380
sprintf(buf, "R: %d, G: %d, B: %d, A: %d", pxl[0], pxl[1], pxl[2], pxl[3]);
293
sprintf(buf, "R: %d, G: %d, B: %d, A: %d", pxl[0], pxl[1], pxl[2], pxl[3]);
294
383
renderwin_set_infotext(rw, buf);
295
384
renderwin_queue_redraw(rw);
549
static char *renderwin_get_title(int doswap)
557
if (G.scene->r.renderer==R_YAFRAY) title = "YafRay:Render (spare)";
558
else title = "Blender:Render (spare)";
561
if (G.scene->r.renderer==R_YAFRAY) title = "YafRay:Render";
562
else title = "Blender:Render";
449
568
/* opens window and allocs struct */
450
569
static void open_renderwin(int winpos[2], int winsize[2])
571
extern void mywindow_build_and_set_renderwin( int orx, int ory, int sizex, int sizey); // mywindow.c
453
/* yafray: Window title change for yafray, totally unnecessary of course, but... */
455
if (G.scene->r.renderer==R_YAFRAY)
456
title = "YafRay:Render";
458
title = "Blender:Render";
460
win= window_open(title, winpos[0], winpos[1], winsize[0], winsize[1], 0);
575
title= renderwin_get_title(0); /* 0 = no swap */
576
win= window_open(title, winpos[0], winpos[1], winsize[0], winsize[1]+RW_HEADERY, 0);
462
578
render_win= renderwin_alloc(win);
467
583
winlay_process_events(0);
468
584
window_make_active(render_win->win);
469
585
winlay_process_events(0);
587
/* mywindow has to know about it too */
588
mywindow_build_and_set_renderwin(winpos[0], winpos[1], winsize[0], winsize[1]+RW_HEADERY);
589
/* and we should be able to draw 3d in it */
471
592
renderwin_draw(render_win, 1);
472
593
renderwin_draw(render_win, 1);
489
610
rendersize_r[0]= (G.scene->r.size*G.scene->r.xsch)/100;
490
611
rendersize_r[1]= (G.scene->r.size*G.scene->r.ysch)/100;
613
/* crop option makes image smaller */
614
if ((G.scene->r.mode & R_BORDER) && (G.scene->r.mode & R_MOVIECROP)) {
615
rendersize_r[0]*= (G.scene->r.border.xmax-G.scene->r.border.xmin);
616
rendersize_r[1]*= (G.scene->r.border.ymax-G.scene->r.border.ymin);
491
619
if(G.scene->r.mode & R_PANORAMA) {
492
620
rendersize_r[0]*= G.scene->r.xparts;
493
621
rendersize_r[1]*= G.scene->r.yparts;
533
661
window_get_position(render_win->win, &win_x, &win_y);
534
662
window_get_size(render_win->win, &win_w, &win_h);
536
665
/* XXX, this is nasty and I guess bound to cause problems,
537
666
* but to ensure the window is at the user specified position
538
667
* and size we reopen the window all the time... we need
539
668
* a ghost _set_position to fix this -zr
541
BIF_close_render_display();
542
open_renderwin(renderpos, rendersize);
671
/* XXX, well... it is nasty yes, and reopens windows each time on
672
subsequent renders. Better rule is to make it reopen only only
673
size change, and use the preferred position only on open_renderwin
676
if(rendersize[0]!= win_w || rendersize[1]!= win_h) {
677
BIF_close_render_display();
678
open_renderwin(renderpos, rendersize);
681
window_raise(render_win->win);
682
window_make_active(render_win->win);
683
mywinset(2); // to assign scissor/viewport again in mywindow.c. is hackish yes
544
686
renderwin_reset_view(render_win);
545
687
render_win->flags&= ~RW_FLAGS_ESCAPE;
546
688
render_win->active= 1;
690
/* make sure we are in normal draw again */
691
render_win->flags &= ~RW_FLAGS_ALPHA;
573
719
win_rct.xmin= win_rct.ymin= 0;
574
720
window_get_size(rw->win, &win_rct.xmax, &win_rct.ymax);
721
win_rct.ymax-= RW_HEADERY;
575
723
renderwin_get_disprect(rw, disprect);
577
window_make_active(rw->win);
725
/* for efficiency & speed; not drawing in Blender UI while rendering */
726
//window_make_active(rw->win);
579
728
glEnable(GL_SCISSOR_TEST);
580
729
glaDefine2DArea(&win_rct);
637
786
rcti win_rct, vb;
639
788
calc_viewborder(v3d, &vb);
790
/* if border render */
791
if(G.scene->r.mode & R_BORDER) {
793
/* but, if image is full (at end of border render, without crop) we don't */
794
if(R.rectx != (G.scene->r.size*G.scene->r.xsch)/100 ||
795
R.recty != (G.scene->r.size*G.scene->r.ysch)/100 ) {
797
facx= (float) (vb.xmax-vb.xmin);
798
facy= (float) (vb.ymax-vb.ymin);
800
vb.xmax= vb.xmin + facx*G.scene->r.border.xmax;
801
vb.ymax= vb.ymin + facy*G.scene->r.border.ymax;
802
vb.xmin+= facx*G.scene->r.border.xmin;
803
vb.ymin+= facy*G.scene->r.border.ymin;
641
807
facx= (float) (vb.xmax-vb.xmin)/R.rectx;
642
808
facy= (float) (vb.ymax-vb.ymin)/R.recty;
831
/* in 3d view; display stats of rendered image */
832
static void renderview_draw_render_info(char *str)
835
View3D *v3d= render_view3d;
838
calc_viewborder(v3d, &vb);
840
bwin_get_rect(v3d->area->win, &win_rct);
841
glaDefine2DArea(&win_rct);
843
glDrawBuffer(GL_FRONT);
845
/* clear header rect */
846
BIF_ThemeColor(TH_HEADER);
847
glRecti(vb.xmin, vb.ymax, vb.xmax, vb.ymax+RW_HEADERY);
850
BIF_ThemeColor(TH_TEXT);
851
glRasterPos2i(vb.xmin+12, vb.ymax+5);
852
BMF_DrawString(G.fonts, str);
856
glDrawBuffer(GL_BACK);
858
v3d->area->win_swap= WIN_FRONT_OK;
665
864
/* -------------- callbacks for render loop: interactivity ----------------------- */
668
/* callback for print info in top header in interface */
867
/* callback for print info in top header of renderwin */
868
/* time is only not zero on last call, we then don't update the other stats */
669
869
static void printrenderinfo_cb(double time, int sample)
671
871
extern int mem_in_use;
672
float megs_used_memory= mem_in_use/(1024.0*1024.0);
673
char str[300], tstr[32], *spos= str;
872
static int totvert=0, totvlak=0, tothalo=0, totlamp=0;
873
static float megs_used_memory=0.0;
874
char str[300], *spos= str;
676
spos+= sprintf(spos, "RENDER Fra:%d Ve:%d Fa:%d La:%d", (G.scene->r.cfra), R.totvert, R.totvlak, R.totlamp);
677
spos+= sprintf(spos, "Mem:%.2fM Time:%s ", megs_used_memory, tstr);
877
megs_used_memory= mem_in_use/(1024.0*1024.0);
885
spos+= sprintf(spos, "Fra:%d Ve:%d Fa:%d Ha:%d La:%d Mem:%.2fM", (G.scene->r.cfra), totvert, totvlak, tothalo, totlamp, megs_used_memory);
887
spos+= sprintf(spos, "Fra:%d Ve:%d Fa:%d La:%d Mem:%.2fM", (G.scene->r.cfra), totvert, totvlak, totlamp, megs_used_memory);
679
if (R.r.mode & R_FIELDS) {
680
spos+= sprintf(spos, "Field %c ", (R.flag&R_SEC_FIELD)?'B':'A');
890
if (R.r.mode & R_FIELDS) {
891
spos+= sprintf(spos, "Field %c ", (R.flag&R_SEC_FIELD)?'B':'A');
894
spos+= sprintf(spos, "Sample: %d ", sample);
683
spos+= sprintf(spos, "Sample: %d ", sample);
898
extern char info_time_str[32]; // header_info.c
899
timestr(time, info_time_str);
900
spos+= sprintf(spos, " Time:%s ", info_time_str);
686
screen_draw_info_text(G.curscreen, str);
904
if(render_win->render_text) MEM_freeN(render_win->render_text);
905
render_win->render_text= BLI_strdup(str);
906
glDrawBuffer(GL_FRONT);
907
renderwin_draw_render_info(render_win);
909
glDrawBuffer(GL_BACK);
911
else renderview_draw_render_info(str);
689
914
/* -------------- callback system to allow ESC from rendering ----------------------- */
841
1066
if(anim) update_for_newframe_muted(); // only when anim, causes redraw event which frustrates dispview
844
1068
if (render_win) window_set_cursor(render_win->win, CURSOR_STD);
847
1070
free_filesel_spec(G.scene->r.pic);
850
1073
end_test_break_callback();
852
1075
/* in dispiew it will destroy the image otherwise
853
1076
window_make_active() raises window at osx and sends redraws */
854
if(R.displaymode==R_DISPLAYWIN) mainwindow_make_active();
1077
if(G.displaymode==R_DISPLAYWIN) {
1078
mainwindow_make_active();
1080
/* after an envmap creation... */
1081
if(R.flag & R_REDRAW_PRV) {
1082
BIF_all_preview_changed();
1084
allqueue(REDRAWBUTSSCENE, 0); // visualize fbuf for example
1088
waitcursor(0); // waitcursor checks rendering R.flag...
858
1091
/* finds area with a 'dispview' set */
898
1131
/* -------------- API: externally called --------------- */
1133
/* not used anywhere ??? */
1135
void BIF_renderwin_make_active(void)
1138
window_make_active(render_win->win);
900
1144
/* set up display, render an image or scene */
901
1145
void BIF_do_render(int anim)
903
do_render(NULL, anim, 0);
1149
if (G.f & G_DOSCRIPTLINKS) {
1150
BPY_do_all_scripts(SCRIPT_RENDER);
1151
if (!anim) { /* avoid FRAMECHANGED slink in render callback */
1152
G.f &= ~G_DOSCRIPTLINKS;
1157
/* if start render in 3d win, use layer from window (e.g also local view) */
1158
if(curarea && curarea->spacetype==SPACE_VIEW3D) {
1159
int lay= G.scene->lay;
1160
if(G.vd->lay & 0xFF000000) // localview
1161
G.scene->lay |= G.vd->lay;
1162
else G.scene->lay= G.vd->lay;
1164
do_render(NULL, anim, 0);
1168
else do_render(NULL, anim, 0);
1170
if (slink_flag) G.f |= G_DOSCRIPTLINKS;
1171
if (G.f & G_DOSCRIPTLINKS) BPY_do_all_scripts(SCRIPT_POSTRENDER);
906
1174
/* set up display, render the current area view in an image */
911
1179
G.scene->r.scemode &= ~R_OGL;
1182
void BIF_redraw_render_rect(void)
1186
if (G.displaymode == R_DISPLAYWIN) {
1187
// don't open render_win if rendering has been
1188
// canceled or the render_win has been actively closed
1190
renderwin_queue_redraw(render_win);
1193
renderview_init_display_cb();
1194
renderview_progress_display_cb(0, R.recty-1, R.rectx, R.recty, R.rectot);
914
1198
void BIF_swap_render_rects(void)
916
1200
unsigned int *temp;
935
1219
R.rectot= R.rectspare;
936
1220
R.rectspare= temp;
939
if (R.displaymode == R_DISPLAYWIN) {
940
// don't open render_win if rendering has been
941
// canceled or the render_win has been actively closed
1222
if (G.displaymode == R_DISPLAYWIN) {
942
1223
if (render_win) {
943
renderwin_queue_redraw(render_win);
1224
char *tmp= render_win->render_text_spare;
1225
render_win->render_text_spare= render_win->render_text;
1226
render_win->render_text= tmp;
1228
window_set_title(render_win->win, renderwin_get_title(1));
946
renderview_init_display_cb();
947
renderview_progress_display_cb(0, R.recty-1, R.rectx, R.recty, R.rectot);
1234
BIF_redraw_render_rect();
951
1237
/* called from usiblender.c too, to free and close renderwin */