~ubuntu-branches/ubuntu/gutsy/blender/gutsy-security

« back to all changes in this revision

Viewing changes to source/blender/src/renderwin.c

  • Committer: Bazaar Package Importer
  • Author(s): Lukas Fittl
  • Date: 2006-09-20 01:57:27 UTC
  • mfrom: (1.2.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20060920015727-gmoqlxwstx9wwqs3
Tags: 2.42a-1ubuntu1
* Merge from Debian unstable (Closes: Malone #55903). Remaining changes:
  - debian/genpot: Add python scripts from Lee June <blender@eyou.com> to
    generate a reasonable PO template from the sources. Since gettext is used
    in a highly nonstandard way, xgettext does not work for this job.
  - debian/rules: Call the scripts, generate po/blender.pot, and clean it up
    in the clean target.
  - Add a proper header to the generated PO template.
* debian/control: Build depend on libavformat-dev >= 3:0.cvs20060823-3.1,
  otherwise this package will FTBFS

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/**
2
 
 * $Id: renderwin.c,v 1.64 2006/01/18 20:06:13 khughes Exp $
 
2
 * $Id: renderwin.c,v 1.108 2006/07/18 16:49:33 ton Exp $
3
3
 *
4
4
 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5
5
 *
56
56
#include <limits.h>
57
57
 
58
58
#include "BLI_blenlib.h"
 
59
#include "BLI_threads.h"
59
60
 
60
61
#include "MEM_guardedalloc.h"
61
62
 
62
63
#include "BMF_Api.h"
63
64
 
 
65
#include "DNA_image_types.h"
 
66
#include "DNA_screen_types.h"
 
67
#include "DNA_scene_types.h"
64
68
#include "DNA_view3d_types.h"
65
 
#include "DNA_screen_types.h"
66
69
#include "DNA_vec_types.h"
67
70
 
68
71
#include "BKE_global.h"
 
72
#include "BKE_image.h"
 
73
#include "BKE_library.h"
69
74
#include "BKE_scene.h"
70
75
#include "BKE_utildefines.h"
 
76
#include "BKE_writeavi.h"       /* movie handle */
71
77
 
 
78
#include "BIF_drawimage.h"
72
79
#include "BIF_gl.h"
73
80
#include "BIF_glutil.h"
74
81
#include "BIF_graphics.h"
75
82
#include "BIF_screen.h"
76
83
#include "BIF_space.h"
77
84
#include "BIF_mywindow.h"
78
 
#include "BIF_previewrender.h"
79
85
#include "BIF_renderwin.h"
80
86
#include "BIF_resources.h"
81
87
#include "BIF_toets.h"
 
88
#include "BIF_toolbox.h"
 
89
#include "BIF_writeimage.h"
82
90
 
83
91
#include "BDR_editobject.h"
84
92
#include "BPY_extern.h" /* for BPY_do_all_scripts */
88
96
#include "BSE_filesel.h"
89
97
#include "BSE_headerbuttons.h"
90
98
 
 
99
#include "RE_pipeline.h"
 
100
 
 
101
#include "IMB_imbuf.h"
 
102
#include "IMB_imbuf_types.h"
 
103
 
91
104
#include "blendef.h"
92
105
#include "mydevice.h"
93
106
#include "winlay.h"
94
 
#include "render.h"
95
107
 
96
108
/* ------------ renderwin struct, to prevent too much global vars --------- */
97
109
/* ------------ only used for display in a 2nd window  --------- */
117
129
/* forces draw of alpha */
118
130
#define RW_FLAGS_ALPHA          (1<<4)
119
131
 
120
 
/* space for info text */
121
 
#define RW_HEADERY              18
122
132
 
123
133
typedef struct {
124
134
        Window *win;
125
135
 
 
136
        int rectx, recty;       /* size of image */
 
137
        
 
138
        int sparex, sparey;     /* spare rect size */
 
139
        unsigned int *rectspare;
 
140
        float *rectsparef;
 
141
        
126
142
        float zoom, zoomofs[2];
127
143
        int active;
 
144
        short storespare, showspare;
128
145
        
129
146
        int mbut[3];
130
147
        int lmouse[2];
146
163
/* only called in function open_renderwin */
147
164
static RenderWin *renderwin_alloc(Window *win)
148
165
{
149
 
        RenderWin *rw= MEM_mallocN(sizeof(*rw), "RenderWin");
 
166
        RenderWin *rw= MEM_callocN(sizeof(*rw), "RenderWin");
150
167
        rw->win= win;
151
168
        rw->zoom= 1.0;
152
169
        rw->active= 0;
153
170
        rw->flags= 0;
154
171
        rw->zoomofs[0]= rw->zoomofs[1]= 0;
155
172
        rw->info_text= NULL;
156
 
        rw->render_text= rw->render_text_spare= NULL;
 
173
        rw->render_text= MEM_callocN(RW_MAXTEXT, "rendertext");
 
174
        rw->render_text_spare= MEM_callocN(RW_MAXTEXT, "rendertext spare");
157
175
 
158
176
        rw->lmouse[0]= rw->lmouse[1]= 0;
159
177
        rw->mbut[0]= rw->mbut[1]= rw->mbut[2]= 0;
172
190
        ;
173
191
}
174
192
 
175
 
static void renderwin_get_disprect(RenderWin *rw, float disprect_r[2][2])
 
193
static void renderwin_get_fullrect(RenderWin *rw, float fullrect_r[2][2])
176
194
{
177
195
        float display_w, display_h;
178
196
        float cent_x, cent_y;
181
199
        window_get_size(rw->win, &w, &h);
182
200
        h-= RW_HEADERY;
183
201
 
184
 
        display_w= R.rectx*rw->zoom;
185
 
        display_h= R.recty*rw->zoom;
186
 
        cent_x= (rw->zoomofs[0] + R.rectx/2)*rw->zoom;
187
 
        cent_y= (rw->zoomofs[1] + R.recty/2)*rw->zoom;
 
202
        display_w= rw->rectx*rw->zoom;
 
203
        display_h= rw->recty*rw->zoom;
 
204
        cent_x= (rw->zoomofs[0] + rw->rectx/2)*rw->zoom;
 
205
        cent_y= (rw->zoomofs[1] + rw->recty/2)*rw->zoom;
188
206
        
189
 
        disprect_r[0][0]= w/2 - cent_x;
190
 
        disprect_r[0][1]= h/2 - cent_y;
191
 
        disprect_r[1][0]= disprect_r[0][0] + display_w;
192
 
        disprect_r[1][1]= disprect_r[0][1] + display_h;
 
207
        fullrect_r[0][0]= w/2 - cent_x;
 
208
        fullrect_r[0][1]= h/2 - cent_y;
 
209
        fullrect_r[1][0]= fullrect_r[0][0] + display_w;
 
210
        fullrect_r[1][1]= fullrect_r[0][1] + display_h;
193
211
}
194
212
 
195
213
        /** 
198
216
         */
199
217
static int renderwin_win_to_image_co(RenderWin *rw, int winco[2], int imgco_r[2])
200
218
{
201
 
        float disprect[2][2];
202
 
        
203
 
        renderwin_get_disprect(rw, disprect);
204
 
        
205
 
        imgco_r[0]= (int) ((winco[0]-disprect[0][0])/rw->zoom);
206
 
        imgco_r[1]= (int) ((winco[1]-disprect[0][1])/rw->zoom);
207
 
        
208
 
        return (imgco_r[0]>=0 && imgco_r[1]>=0 && imgco_r[0]<R.rectx && imgco_r[1]<R.recty);
 
219
        float fullrect[2][2];
 
220
        
 
221
        renderwin_get_fullrect(rw, fullrect);
 
222
        
 
223
        imgco_r[0]= (int) ((winco[0]-fullrect[0][0])/rw->zoom);
 
224
        imgco_r[1]= (int) ((winco[1]-fullrect[0][1])/rw->zoom);
 
225
        
 
226
        return (imgco_r[0]>=0 && imgco_r[1]>=0 && imgco_r[0]<rw->rectx && imgco_r[1]<rw->recty);
209
227
}
210
228
 
211
229
        /**
233
251
 
234
252
static void renderwin_reset_view(RenderWin *rw)
235
253
{
236
 
        int w, h, rectx, recty;
 
254
        int w, h;
237
255
 
238
256
        if (rw->info_text) renderwin_set_infotext(rw, NULL);
239
257
 
240
258
        /* now calculate a zoom for when image is larger than window */
241
259
        window_get_size(rw->win, &w, &h);
242
260
        h-= RW_HEADERY;
243
 
        
244
 
        /* at this point the r.rectx/y values are not correct yet */
245
 
        rectx= (G.scene->r.size*G.scene->r.xsch)/100;
246
 
        recty= (G.scene->r.size*G.scene->r.ysch)/100;
247
 
        
248
 
        /* crop option makes image smaller */
249
 
        if ((G.scene->r.mode & R_BORDER) && (G.scene->r.mode & R_MOVIECROP)) { 
250
 
                if(!(G.scene->r.scemode & R_OGL)) {
251
 
                        rectx= (int) (rectx*(G.scene->r.border.xmax-G.scene->r.border.xmin));
252
 
                        recty= (int) (recty*(G.scene->r.border.ymax-G.scene->r.border.ymin));
253
 
                }
254
 
        }
255
 
        
256
 
        if(rectx>w || recty>h) {
257
 
                if(rectx-w > recty-h) rw->zoom= ((float)w)/((float)rectx);
258
 
                else rw->zoom= ((float)h)/((float)recty);
 
261
 
 
262
        if(rw->rectx>w || rw->recty>h) {
 
263
                if(rw->rectx-w > rw->recty-h) rw->zoom= ((float)w)/((float)rw->rectx);
 
264
                else rw->zoom= ((float)h)/((float)rw->recty);
259
265
        }
260
266
        else rw->zoom= 1.0;
261
267
 
269
275
        if(RW_HEADERY) {
270
276
                float colf[3];
271
277
                rcti rect;
 
278
                char *str;
272
279
                
273
280
                window_get_size(rw->win, &rect.xmax, &rect.ymax);
274
281
                rect.xmin= 0;
282
289
                glClearColor(colf[0], colf[1], colf[2], 1.0); 
283
290
                glClear(GL_COLOR_BUFFER_BIT);
284
291
                
285
 
                if(rw->render_text) {
 
292
                if(rw->showspare)
 
293
                        str= rw->render_text_spare;
 
294
                else
 
295
                        str= rw->render_text;
 
296
                
 
297
                if(str) {
286
298
                        BIF_ThemeColor(TH_TEXT);
287
299
                        glRasterPos2i(12, 5);
288
 
                        BMF_DrawString(G.fonts, rw->render_text);
 
300
                        BMF_DrawString(G.fonts, str);
289
301
                }
290
302
                
291
303
                BIF_SetTheme(curarea);  // restore theme
295
307
 
296
308
static void renderwin_draw(RenderWin *rw, int just_clear)
297
309
{
298
 
        float disprect[2][2];
 
310
        float fullrect[2][2];
299
311
        int set_back_mainwindow;
300
312
        rcti rect;
301
 
        
 
313
 
302
314
        /* since renderwin uses callbacks (controlled by ghost) it can
303
 
           mess up active window output with redraw events after a render. 
304
 
           this is patchy, still WIP */
 
315
                mess up active window output with redraw events after a render. 
 
316
                this is patchy, still WIP */
305
317
        set_back_mainwindow = (winlay_get_active_window() != rw->win);
306
318
        window_make_active(rw->win);
307
319
        
309
321
        window_get_size(rw->win, &rect.xmax, &rect.ymax);
310
322
        rect.ymax-= RW_HEADERY;
311
323
        
312
 
        renderwin_get_disprect(rw, disprect);
 
324
        renderwin_get_fullrect(rw, fullrect);
313
325
        
314
326
        /* do this first, so window ends with correct scissor */
315
327
        renderwin_draw_render_info(rw);
320
332
        glClearColor(.1875, .1875, .1875, 1.0); 
321
333
        glClear(GL_COLOR_BUFFER_BIT);
322
334
 
323
 
        if (just_clear || !R.rectot) {
 
335
        if (just_clear) {
324
336
                glColor3ub(0, 0, 0);
325
 
                glRectfv(disprect[0], disprect[1]);
 
337
                glRectfv(fullrect[0], fullrect[1]);
326
338
        } else {
327
 
                glPixelZoom(rw->zoom, rw->zoom);
328
 
                if(rw->flags & RW_FLAGS_ALPHA) {
329
 
                        char *rect= (char *)R.rectot;
330
 
                        
331
 
                        glColorMask(1, 0, 0, 0);
332
 
                        glaDrawPixelsSafe(disprect[0][0], disprect[0][1], R.rectx, R.recty, rect+3);
333
 
                        glColorMask(0, 1, 0, 0);
334
 
                        glaDrawPixelsSafe(disprect[0][0], disprect[0][1], R.rectx, R.recty, rect+2);
335
 
                        glColorMask(0, 0, 1, 0);
336
 
                        glaDrawPixelsSafe(disprect[0][0], disprect[0][1], R.rectx, R.recty, rect+1);
337
 
                        glColorMask(1, 1, 1, 1);
338
 
                        
339
 
                }
340
 
                else {
341
 
                        glaDrawPixelsSafe(disprect[0][0], disprect[0][1], R.rectx, R.recty, R.rectot);
342
 
                }
343
 
                glPixelZoom(1.0, 1.0);
 
339
                RenderResult rres;
 
340
                
 
341
                if(rw->showspare) {
 
342
                        rres.rectx= rw->sparex;
 
343
                        rres.recty= rw->sparey;
 
344
                        rres.rect32= rw->rectspare;
 
345
                        rres.rectf= rw->rectsparef;
 
346
                }
 
347
                else
 
348
                        RE_GetResultImage(RE_GetRender(G.scene->id.name), &rres);
 
349
                
 
350
                if(rres.rectf || rres.rect32) {
 
351
                        
 
352
                        glPixelZoom(rw->zoom, rw->zoom);
 
353
                        if(rw->flags & RW_FLAGS_ALPHA) {
 
354
                                if(rres.rect32) {
 
355
                                        /* swap bytes, so alpha is most significant one, then just draw it as luminance int */
 
356
                                        if(G.order==B_ENDIAN)
 
357
                                                glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
 
358
                                        glaDrawPixelsSafe(fullrect[0][0], fullrect[0][1], rres.rectx, rres.recty, rres.rectx, GL_LUMINANCE, GL_UNSIGNED_INT, rres.rect32);
 
359
                                        glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
 
360
                                }
 
361
                                else {
 
362
                                        float *trectf= MEM_mallocN(rres.rectx*rres.recty*4, "temp");
 
363
                                        int a, b;
 
364
                                        
 
365
                                        for(a= rres.rectx*rres.recty -1, b= 4*a+3; a>=0; a--, b-=4)
 
366
                                                trectf[a]= rres.rectf[b];
 
367
                                        
 
368
                                        glaDrawPixelsSafe(fullrect[0][0], fullrect[0][1], rres.rectx, rres.recty, rres.rectx, GL_LUMINANCE, GL_FLOAT, trectf);
 
369
                                        MEM_freeN(trectf);
 
370
                                }
 
371
                        }
 
372
                        else {
 
373
                                if(rres.rect32)
 
374
                                        glaDrawPixelsSafe(fullrect[0][0], fullrect[0][1], rres.rectx, rres.recty, rres.rectx, GL_RGBA, GL_UNSIGNED_BYTE, rres.rect32);
 
375
                                else if(rres.rectf)
 
376
                                        glaDrawPixelsSafe_to32(fullrect[0][0], fullrect[0][1], rres.rectx, rres.recty, rres.rectx, rres.rectf);
 
377
                        }
 
378
                        glPixelZoom(1.0, 1.0);
 
379
                }
344
380
        }
345
381
        
346
382
        /* info text is overlayed on bottom */
366
402
 
367
403
static void renderwin_mouse_moved(RenderWin *rw)
368
404
{
 
405
        RenderResult rres;
 
406
        
 
407
        RE_GetResultImage(RE_GetRender(G.scene->id.name), &rres);
 
408
 
369
409
        if (rw->flags & RW_FLAGS_PIXEL_EXAMINING) {
370
 
                int imgco[2];
371
 
                char buf[64];
372
 
                int *pxlz;      // zbuffer is signed 
 
410
                int imgco[2], ofs=0;
 
411
                char buf[128];
373
412
                char *pxl;
374
413
 
375
 
                if (R.rectot && renderwin_win_to_image_co(rw, rw->lmouse, imgco)) {
376
 
                        pxl= (char*) &R.rectot[R.rectx*imgco[1] + imgco[0]];
377
 
                        
378
 
                        if (R.rectz) {
379
 
                                pxlz= &R.rectz[R.rectx*imgco[1] + imgco[0]];                    
380
 
                                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) );
381
 
                        }
382
 
                        else {
383
 
                                sprintf(buf, "R: %d, G: %d, B: %d, A: %d", pxl[0], pxl[1], pxl[2], pxl[3]);                     
 
414
                if (renderwin_win_to_image_co(rw, rw->lmouse, imgco)) {
 
415
                        if (rres.rect32) {
 
416
                                pxl= (char*) &rres.rect32[rres.rectx*imgco[1] + imgco[0]];
 
417
                                ofs= sprintf(buf, "R: %d G: %d B: %d A: %d", pxl[0], pxl[1], pxl[2], pxl[3]);   
 
418
                        }
 
419
                        if (rres.rectf) {
 
420
                                float *pxlf= rres.rectf + 4*(rres.rectx*imgco[1] + imgco[0]);
 
421
                                ofs+= sprintf(buf+ofs, " | R: %.3f G: %.3f B: %.3f A: %.3f ", pxlf[0], pxlf[1], pxlf[2], pxlf[3]);
 
422
                        }
 
423
                        if (rres.rectz) {
 
424
                                float *pxlz= &rres.rectz[rres.rectx*imgco[1] + imgco[0]];                       
 
425
                                sprintf(buf+ofs, "| Z: %.3f", *pxlz );
384
426
                        }
385
427
 
386
428
                        renderwin_set_infotext(rw, buf);
396
438
        
397
439
                rw->zoomofs[0]= rw->pan_ofs_start[0] - delta_x/rw->zoom;
398
440
                rw->zoomofs[1]= rw->pan_ofs_start[1] - delta_y/rw->zoom;
399
 
                rw->zoomofs[0]= CLAMPIS(rw->zoomofs[0], -R.rectx/2, R.rectx/2);
400
 
                rw->zoomofs[1]= CLAMPIS(rw->zoomofs[1], -R.recty/2, R.recty/2);
 
441
                rw->zoomofs[0]= CLAMPIS(rw->zoomofs[0], -rres.rectx/2, rres.rectx/2);
 
442
                rw->zoomofs[1]= CLAMPIS(rw->zoomofs[1], -rres.recty/2, rres.recty/2);
401
443
 
402
444
                renderwin_queue_redraw(rw);
403
445
        } 
409
451
                h-= RW_HEADERY;
410
452
                renderwin_win_to_ndc(rw, rw->lmouse, ndc);
411
453
 
412
 
                rw->zoomofs[0]= -0.5*ndc[0]*(w-R.rectx*rw->zoom)/rw->zoom;
413
 
                rw->zoomofs[1]= -0.5*ndc[1]*(h-R.recty*rw->zoom)/rw->zoom;
 
454
                rw->zoomofs[0]= -0.5*ndc[0]*(w-rres.rectx*rw->zoom)/rw->zoom;
 
455
                rw->zoomofs[1]= -0.5*ndc[1]*(h-rres.recty*rw->zoom)/rw->zoom;
414
456
 
415
457
                renderwin_queue_redraw(rw);
416
458
        }
448
490
        RenderWin *rw= user_data;
449
491
 
450
492
        // added this for safety, while render it's just creating bezerk results
451
 
        if(R.flag & R_RENDERING) {
 
493
        if(G.rendering) {
452
494
                if(evt==ESCKEY && val) 
453
495
                        rw->flags|= RW_FLAGS_ESCAPE;
454
496
                return;
498
540
                        renderwin_queue_redraw(render_win);
499
541
                }
500
542
                else if (evt==JKEY) {
501
 
                        if(R.flag==0) BIF_swap_render_rects();
 
543
                        if(G.rendering==0) BIF_swap_render_rects();
502
544
                } 
503
545
                else if (evt==ZKEY) {
504
546
                        if (rw->flags&RW_FLAGS_OLDZOOM) {
531
573
                        renderwin_reset_view(rw);
532
574
                } 
533
575
                else if (evt==F3KEY) {
534
 
                        if(R.flag==0) {
 
576
                        if(G.rendering==0) {
535
577
                                mainwindow_raise();
536
578
                                mainwindow_make_active();
537
579
                                rw->active= 0;
538
580
                                areawinset(find_biggest_area()->win);
539
 
                                BIF_save_rendered_image();
 
581
                                BIF_save_rendered_image_fs(0);
540
582
                        }
541
583
                } 
542
584
                else if (evt==F11KEY) {
543
585
                        BIF_toggle_render_display();
544
586
                } 
545
587
                else if (evt==F12KEY) {
546
 
                        /* if it's rendering, this flag is set */
547
 
                        if(R.flag==0) BIF_do_render(0);
 
588
                        if(G.rendering==0) 
 
589
                                BIF_do_render(0);
548
590
                }
549
591
        }
550
592
}
557
599
        swap+= doswap;
558
600
        
559
601
        if(swap & 1) {
560
 
                if (G.scene->r.renderer==R_YAFRAY) title = "YafRay:Render (spare)";
561
 
                else title = "Blender:Render (spare)";
 
602
                if (G.scene->r.renderer==R_YAFRAY) title = "YafRay:Render (previous)";
 
603
                else title = "Blender:Render (previous)";
562
604
        }
563
605
        else {
564
606
                if (G.scene->r.renderer==R_YAFRAY) title = "YafRay:Render";
569
611
}
570
612
 
571
613
/* opens window and allocs struct */
572
 
static void open_renderwin(int winpos[2], int winsize[2])
 
614
static void open_renderwin(int winpos[2], int winsize[2], int imagesize[2])
573
615
{
574
616
        extern void mywindow_build_and_set_renderwin( int orx, int ory, int sizex, int sizey); // mywindow.c
575
617
        Window *win;
579
621
        win= window_open(title, winpos[0], winpos[1], winsize[0], winsize[1]+RW_HEADERY, 0);
580
622
 
581
623
        render_win= renderwin_alloc(win);
582
 
 
 
624
        render_win->rectx= imagesize[0];
 
625
        render_win->recty= imagesize[1];
 
626
        
583
627
        /* Ghost calls handler */
584
628
        window_set_handler(win, renderwin_handler, render_win);
585
629
 
599
643
/* -------------- callbacks for render loop: Window (RenderWin) ----------------------- */
600
644
 
601
645
/* calculations for window size and position */
602
 
void calc_renderwin_rectangle(int posmask, int renderpos_r[2], int rendersize_r[2]) 
 
646
void calc_renderwin_rectangle(int rectx, int recty, int posmask, int renderpos_r[2], int rendersize_r[2]) 
603
647
{
604
648
        int scr_w, scr_h, x, y, div= 0;
605
649
        float ndc_x= 0.0, ndc_y= 0.0;
606
650
 
607
651
        winlay_get_screensize(&scr_w, &scr_h);
608
652
 
609
 
        rendersize_r[0]= (G.scene->r.size*G.scene->r.xsch)/100;
610
 
        rendersize_r[1]= (G.scene->r.size*G.scene->r.ysch)/100;
611
 
        
612
 
        /* crop option makes image smaller */
613
 
        if ((G.scene->r.mode & R_BORDER) && (G.scene->r.mode & R_MOVIECROP)) { 
614
 
                rendersize_r[0]*= (G.scene->r.border.xmax-G.scene->r.border.xmin);
615
 
                rendersize_r[1]*= (G.scene->r.border.ymax-G.scene->r.border.ymin);
616
 
        }
617
 
        
618
 
        if(G.scene->r.mode & R_PANORAMA) {
619
 
                rendersize_r[0]*= G.scene->r.xparts;
620
 
                rendersize_r[1]*= G.scene->r.yparts;
621
 
        }
 
653
        rendersize_r[0]= rectx;
 
654
        rendersize_r[1]= recty;
622
655
 
623
656
        rendersize_r[0]= CLAMPIS(rendersize_r[0], 0, scr_w);     
624
657
        rendersize_r[1]= CLAMPIS(rendersize_r[1], 0, scr_h-RW_HEADERY);  
649
682
}
650
683
        
651
684
/* init renderwin, alloc/open/resize */
652
 
static void renderwin_init_display_cb(void) 
 
685
static void renderwin_init_display_cb(RenderResult *rr) 
653
686
{
654
 
        if (G.afbreek == 0) {
655
 
                int rendersize[2], renderpos[2];
 
687
        if (G.afbreek != 1) {
 
688
                int rendersize[2], renderpos[2], imagesize[2];
656
689
 
657
 
                calc_renderwin_rectangle(G.winpos, renderpos, rendersize);
 
690
                calc_renderwin_rectangle(rr->rectx, rr->recty, G.winpos, renderpos, rendersize);
 
691
                
 
692
                imagesize[0]= rr->rectx;
 
693
                imagesize[1]= rr->recty;
658
694
 
659
695
                if (!render_win) {
660
 
                        open_renderwin(renderpos, rendersize);
 
696
                        open_renderwin(renderpos, rendersize, imagesize);
661
697
                        renderwin_reset_view(render_win); // incl. autozoom for large images
662
698
                } else {
663
699
                        int win_x, win_y;
680
716
                                 */
681
717
                        if(rendersize[0]!= win_w || rendersize[1]!= win_h) {
682
718
                                BIF_close_render_display();
683
 
                                open_renderwin(renderpos, rendersize);
 
719
                                open_renderwin(renderpos, rendersize, imagesize);
684
720
                        }
685
721
                        else {
686
722
                                window_raise(render_win->win);
697
733
                        }
698
734
 
699
735
                        renderwin_reset_view(render_win);
700
 
                        render_win->flags&= ~RW_FLAGS_ESCAPE;
701
736
                        render_win->active= 1;
702
737
                }
703
738
                /* make sure we are in normal draw again */
704
739
                render_win->flags &= ~RW_FLAGS_ALPHA;
 
740
                
 
741
                glFinish();
705
742
        }
706
743
}
707
744
 
708
745
/* callback for redraw render win */
709
 
static void renderwin_clear_display_cb(short ignore) 
 
746
static void renderwin_clear_display_cb(RenderResult *rr) 
710
747
{
711
748
        if (render_win) {
712
 
                window_make_active(render_win->win);    
 
749
                window_make_active(render_win->win);
713
750
                renderwin_draw(render_win, 1);
714
751
        }
715
752
}
723
760
* Note: blocked queue handling while rendering to prevent that (ton)
724
761
*/
725
762
 
726
 
/* in render window; display a couple of scanlines of rendered image (see callback below) */
727
 
static void renderwin_progress(RenderWin *rw, int start_y, int nlines, int rect_w, int rect_h, unsigned char *rect)
 
763
/* can get as well the full picture, as the parts while rendering */
 
764
static void renderwin_progress(RenderWin *rw, RenderResult *rr, volatile rcti *renrect)
728
765
{
729
 
        float disprect[2][2];
730
766
        rcti win_rct;
731
 
 
 
767
        float *rectf= NULL, fullrect[2][2];
 
768
        unsigned int *rect32= NULL;
 
769
        int ymin, ymax, xmin, xmax;
 
770
        
 
771
        /* if renrect argument, we only display scanlines */
 
772
        if(renrect) {
 
773
                 /* if ymax==recty, rendering of layer is ready, we should not draw, other things happen... */
 
774
                if(rr->renlay==NULL || renrect->ymax>=rr->recty)
 
775
                        return;
 
776
                
 
777
                /* xmin here is first subrect x coord, xmax defines subrect width */
 
778
                xmin = renrect->xmin;
 
779
                xmax = renrect->xmax - xmin;
 
780
                if (xmax<2) return;
 
781
                
 
782
                ymin= renrect->ymin;
 
783
                ymax= renrect->ymax - ymin;
 
784
                if(ymax<2)
 
785
                        return;
 
786
                renrect->ymin= renrect->ymax;
 
787
        }
 
788
        else {
 
789
                xmin = ymin = 0;
 
790
                xmax = rr->rectx - 2*rr->crop;
 
791
                ymax = rr->recty - 2*rr->crop;
 
792
        }
 
793
        
 
794
        /* renderwindow cruft */
732
795
        win_rct.xmin= win_rct.ymin= 0;
733
796
        window_get_size(rw->win, &win_rct.xmax, &win_rct.ymax);
734
797
        win_rct.ymax-= RW_HEADERY;
735
 
        
736
 
        renderwin_get_disprect(rw, disprect);
737
 
        
738
 
        /* for efficiency & speed; not drawing in Blender UI while rendering */
739
 
        //window_make_active(rw->win);
 
798
        renderwin_get_fullrect(rw, fullrect);
 
799
        
 
800
        /* find current float rect for display, first case is after composit... still weak */
 
801
        if(rr->rectf)
 
802
                rectf= rr->rectf;
 
803
        else {
 
804
                if(rr->rect32)
 
805
                        rect32= rr->rect32;
 
806
                else {
 
807
                        if(rr->renlay==NULL || rr->renlay->rectf==NULL) return;
 
808
                        rectf= rr->renlay->rectf;
 
809
                }
 
810
        }
 
811
        if(rectf) {
 
812
                /* if scanline updates... */
 
813
                rectf+= 4*(rr->rectx*ymin + xmin);
 
814
        
 
815
                /* when rendering more pixels than needed, we crop away cruft */
 
816
                if(rr->crop)
 
817
                        rectf+= 4*(rr->crop*rr->rectx + rr->crop);
 
818
        }
 
819
        
 
820
        /* tilerect defines drawing offset from (0,0) */
 
821
        /* however, tilerect (xmin, ymin) is first pixel */
 
822
        fullrect[0][0] += (rr->tilerect.xmin + rr->crop + xmin)*rw->zoom;
 
823
        fullrect[0][1] += (rr->tilerect.ymin + rr->crop + ymin)*rw->zoom;
740
824
 
741
825
        glEnable(GL_SCISSOR_TEST);
742
826
        glaDefine2DArea(&win_rct);
743
827
 
 
828
#ifdef __APPLE__
 
829
#else
744
830
        glDrawBuffer(GL_FRONT);
 
831
#endif
745
832
        glPixelZoom(rw->zoom, rw->zoom);
746
 
        glaDrawPixelsSafe(disprect[0][0], disprect[0][1] + start_y*rw->zoom, rect_w, nlines, &rect[start_y*rect_w*4]);
 
833
 
 
834
        if(rect32)
 
835
                glaDrawPixelsSafe(fullrect[0][0], fullrect[0][1], xmax, ymax, rr->rectx, GL_RGBA, GL_UNSIGNED_BYTE, rect32);
 
836
        else
 
837
                glaDrawPixelsSafe_to32(fullrect[0][0], fullrect[0][1], xmax, ymax, rr->rectx, rectf);
 
838
        
747
839
        glPixelZoom(1.0, 1.0);
 
840
        
 
841
#ifdef __APPLE__
 
842
        window_swap_buffers(render_win->win);
 
843
#else
748
844
        glFlush();
749
845
        glDrawBuffer(GL_BACK);
 
846
#endif  
750
847
}
751
848
 
752
849
 
753
850
/* in render window; display a couple of scanlines of rendered image */
754
 
static void renderwin_progress_display_cb(int y1, int y2, int w, int h, unsigned int *rect)
 
851
static void renderwin_progress_display_cb(RenderResult *rr, volatile rcti *rect)
755
852
{
756
853
        if (render_win) {
757
 
                renderwin_progress(render_win, y1, y2-y1+1, w, h, (unsigned char*) rect);
758
 
        }
759
 
}
760
 
 
761
 
 
762
 
/* -------------- callbacks for render loop: in View3D ----------------------- */
763
 
 
764
 
 
765
 
static View3D *render_view3d = NULL;
766
 
 
767
 
/* init Render view callback */
768
 
static void renderview_init_display_cb(void)
769
 
{
770
 
        ScrArea *sa;
771
 
 
772
 
                /* Choose the first view with a persp camera,
773
 
                 * if one doesn't exist we will get the first
774
 
                 * View3D window.
775
 
                 */ 
776
 
        render_view3d= NULL;
777
 
        for (sa= G.curscreen->areabase.first; sa; sa= sa->next) {
778
 
                if (sa->win && sa->spacetype==SPACE_VIEW3D) {
779
 
                        View3D *vd= sa->spacedata.first;
780
 
                        
781
 
                        if (vd->persp==2 && vd->camera==G.scene->camera) {
782
 
                                render_view3d= vd;
783
 
                                break;
784
 
                        } else if (!render_view3d) {
785
 
                                render_view3d= vd;
786
 
                        }
787
 
                }
788
 
        }
789
 
}
790
 
 
791
 
 
792
 
/* in 3d view; display a couple of scanlines of rendered image */
793
 
static void renderview_progress_display_cb(int y1, int y2, int w, int h, unsigned int *rect)
794
 
{
795
 
        if (render_view3d) {
796
 
                View3D *v3d= render_view3d;
797
 
                int nlines= y2-y1+1;
798
 
                float sx, sy, facx, facy;
799
 
                rcti win_rct, vb;
800
 
 
801
 
                calc_viewborder(v3d, &vb);
802
 
                
803
 
                /* if border render  */
804
 
                if(G.scene->r.mode & R_BORDER) { 
805
 
                        
806
 
                        /* but, if image is full (at end of border render, without crop) we don't */
807
 
                        if(R.rectx != (G.scene->r.size*G.scene->r.xsch)/100 ||
808
 
                           R.recty != (G.scene->r.size*G.scene->r.ysch)/100 ) {
809
 
                        
810
 
                                facx= (float) (vb.xmax-vb.xmin);
811
 
                                facy= (float) (vb.ymax-vb.ymin);
812
 
                                
813
 
                                vb.xmax= vb.xmin + facx*G.scene->r.border.xmax;
814
 
                                vb.ymax= vb.ymin + facy*G.scene->r.border.ymax;
815
 
                                vb.xmin+= facx*G.scene->r.border.xmin;
816
 
                                vb.ymin+= facy*G.scene->r.border.ymin;
817
 
                        }
818
 
                }
819
 
                        
820
 
                facx= (float) (vb.xmax-vb.xmin)/R.rectx;
821
 
                facy= (float) (vb.ymax-vb.ymin)/R.recty;
822
 
 
823
 
                bwin_get_rect(v3d->area->win, &win_rct);
824
 
 
825
 
                glaDefine2DArea(&win_rct);
826
 
        
827
 
                glDrawBuffer(GL_FRONT);
828
 
                
829
 
                sx= vb.xmin;
830
 
                sy= vb.ymin + facy*y1;
831
 
 
832
 
                glPixelZoom(facx, facy);
833
 
                glaDrawPixelsSafe(sx, sy, w, nlines, rect+w*y1);
834
 
                glPixelZoom(1.0, 1.0);
835
 
 
836
 
                glFlush();
837
 
                glDrawBuffer(GL_BACK);
838
 
                v3d->flag |= V3D_DISPIMAGE;
839
 
                v3d->area->win_swap= WIN_FRONT_OK;
840
 
                
841
 
        }
842
 
}
843
 
 
844
 
/* in 3d view; display stats of rendered image */
845
 
static void renderview_draw_render_info(char *str)
846
 
{
847
 
        if (render_view3d) {
848
 
                View3D *v3d= render_view3d;
849
 
                rcti vb, win_rct;
850
 
                
851
 
                calc_viewborder(v3d, &vb);
852
 
                
853
 
                bwin_get_rect(v3d->area->win, &win_rct);
854
 
                glaDefine2DArea(&win_rct);
855
 
                
856
 
                glDrawBuffer(GL_FRONT);
857
 
                
858
 
                /* clear header rect */
859
 
                BIF_ThemeColor(TH_HEADER);
860
 
                glRecti(vb.xmin, vb.ymax, vb.xmax, vb.ymax+RW_HEADERY);
861
 
                
862
 
                if(str) {
863
 
                        BIF_ThemeColor(TH_TEXT);
864
 
                        glRasterPos2i(vb.xmin+12, vb.ymax+5);
865
 
                        BMF_DrawString(G.fonts, str);
866
 
                }
867
 
                
868
 
                glFlush();
869
 
                glDrawBuffer(GL_BACK);
870
 
 
871
 
                v3d->area->win_swap= WIN_FRONT_OK;
872
 
                
873
 
        }
874
 
}
875
 
 
 
854
                renderwin_progress(render_win, rr, rect);
 
855
        }
 
856
}
876
857
 
877
858
/* -------------- callbacks for render loop: interactivity ----------------------- */
878
859
 
 
860
/* string is RW_MAXTEXT chars min */
 
861
void make_renderinfo_string(RenderStats *rs, char *str)
 
862
{
 
863
        extern char info_time_str[32];  // header_info.c
 
864
        extern unsigned long mem_in_use, mmap_in_use;
 
865
        float megs_used_memory, mmap_used_memory;
 
866
        char *spos= str;
 
867
        
 
868
        megs_used_memory= (mem_in_use-mmap_in_use)/(1024.0*1024.0);
 
869
        mmap_used_memory= (mmap_in_use)/(1024.0*1024.0);
 
870
        
 
871
        if(G.scene->lay & 0xFF000000)
 
872
                spos+= sprintf(spos, "Localview | ");
 
873
        else if(G.scene->r.scemode & R_SINGLE_LAYER)
 
874
                spos+= sprintf(spos, "Single Layer | ");
 
875
        
 
876
        if(rs->tothalo)
 
877
                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);
 
878
        else 
 
879
                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);
 
880
        
 
881
        if(rs->curfield)
 
882
                spos+= sprintf(spos, "Field %d ", rs->curfield);
 
883
        if(rs->curblur)
 
884
                spos+= sprintf(spos, "Blur %d ", rs->curblur);
 
885
        
 
886
        BLI_timestr(rs->lastframetime, info_time_str);
 
887
        spos+= sprintf(spos, "Time:%s ", info_time_str);
 
888
        
 
889
        if(rs->infostr)
 
890
                spos+= sprintf(spos, "| %s ", rs->infostr);
 
891
        
 
892
        /* very weak... but 512 characters is quite safe... we cannot malloc during thread render */
 
893
        if(spos >= str+RW_MAXTEXT)
 
894
                printf("WARNING! renderwin text beyond limit \n");
 
895
        
 
896
}
879
897
 
880
898
/* callback for print info in top header of renderwin */
881
 
/* time is only not zero on last call, we then don't update the other stats */ 
882
 
static void printrenderinfo_cb(double time, int sample)
 
899
static void renderwin_renderinfo_cb(RenderStats *rs)
883
900
{
884
 
        extern int mem_in_use;
885
 
        static int totvert=0, totvlak=0, tothalo=0, totlamp=0;
886
 
        static float megs_used_memory=0.0;
887
 
        char str[300], *spos= str;
888
 
                
889
 
        if(time==0.0) {
890
 
                megs_used_memory= mem_in_use/(1024.0*1024.0);
891
 
                totvert= R.totvert;
892
 
                totvlak= R.totvlak;
893
 
                totlamp= R.totlamp;
894
 
                tothalo= R.tothalo;
895
 
        }
896
 
        
897
 
        if(tothalo)
898
 
                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);
899
 
        else 
900
 
                spos+= sprintf(spos, "Fra:%d  Ve:%d Fa:%d La:%d Mem:%.2fM", (G.scene->r.cfra), totvert, totvlak, totlamp, megs_used_memory);
901
 
 
902
 
        if(time==0.0) {
903
 
                if (R.r.mode & R_FIELDS) {
904
 
                        spos+= sprintf(spos, "Field %c ", (R.flag&R_SEC_FIELD)?'B':'A');
905
 
                }
906
 
                if (sample!=-1) {
907
 
                        spos+= sprintf(spos, "Sample: %d    ", sample);
908
 
                }
909
 
        }
910
 
        else {
911
 
                extern char info_time_str[32];  // header_info.c
912
 
                timestr(time, info_time_str);
913
 
                spos+= sprintf(spos, " Time:%s ", info_time_str);
914
 
        }
915
901
        
916
902
        if(render_win) {
917
 
                if(render_win->render_text) MEM_freeN(render_win->render_text);
918
 
                render_win->render_text= BLI_strdup(str);
 
903
                
 
904
                make_renderinfo_string(rs, render_win->render_text);
 
905
                
 
906
#ifdef __APPLE__
 
907
#else
919
908
                glDrawBuffer(GL_FRONT);
 
909
#endif
920
910
                renderwin_draw_render_info(render_win);
 
911
                
 
912
#ifdef __APPLE__
 
913
                window_swap_buffers(render_win->win);
 
914
#else
921
915
                glFlush();
922
916
                glDrawBuffer(GL_BACK);
 
917
#endif
923
918
        }
924
 
        else renderview_draw_render_info(str);
 
919
 
925
920
}
926
921
 
927
922
/* -------------- callback system to allow ESC from rendering ----------------------- */
977
972
#else
978
973
/* all other OS's support signal(SIGVTALRM) */
979
974
 
 
975
/* XXX The ESC problem: some unix users reported that ESC doesn't cancel
 
976
 * renders anymore. Most complaints came from linux, but it's not
 
977
 * general, not all linux users have the problem.
 
978
 *
 
979
 * From tests, the systems that do have it are not signalling SIGVTALRM
 
980
 * interrupts (an issue with signals and threads). Using SIGALRM instead
 
981
 * fixes the problem, at least while we investigate better.
 
982
 *
 
983
 * ITIMER_REAL (SIGALRM): timer that counts real system time
 
984
 * ITIMER_VIRTUAL (SIGVTALRM): only counts time spent in its owner process */
 
985
 
980
986
/* POSIX: this function goes in the signal() callback */
981
987
static void interruptESC(int sig)
982
988
{
984
990
        if(G.afbreek==0) G.afbreek= 2;  /* code for read queue */
985
991
 
986
992
        /* call again, timer was reset */
987
 
        signal(SIGVTALRM, interruptESC);
 
993
        signal(SIGALRM, interruptESC);
988
994
}
989
995
 
990
996
/* POSIX: initialize timer and signal */
995
1001
 
996
1002
        tmevalue.it_interval.tv_sec = 0;
997
1003
        tmevalue.it_interval.tv_usec = 250000;
998
 
        /* wanneer de eerste ? */
 
1004
        /* when the first ? */
999
1005
        tmevalue.it_value.tv_sec = 0;
1000
1006
        tmevalue.it_value.tv_usec = 10000;
1001
1007
 
1002
 
        signal(SIGVTALRM, interruptESC);
1003
 
        setitimer(ITIMER_VIRTUAL, &tmevalue, 0);
1004
 
 
 
1008
        signal(SIGALRM, interruptESC);
 
1009
        setitimer(ITIMER_REAL, &tmevalue, 0);
1005
1010
}
1006
1011
 
1007
1012
/* POSIX: stop timer and callback */
1009
1014
{
1010
1015
        struct itimerval tmevalue;
1011
1016
 
1012
 
        tmevalue.it_value.tv_sec = 0;
1013
 
        tmevalue.it_value.tv_usec = 0;
1014
 
        setitimer(ITIMER_VIRTUAL, &tmevalue, 0);
1015
 
        signal(SIGVTALRM, SIG_IGN);
 
1017
        memset(&tmevalue, 0, sizeof(struct itimerval));
 
1018
 
 
1019
        setitimer(ITIMER_REAL, &tmevalue, 0);
 
1020
        signal(SIGALRM, SIG_IGN);
1016
1021
 
1017
1022
}
1018
1023
 
1025
1030
 
1026
1031
 
1027
1032
/* - initialize displays
1028
 
   - both opengl render as blender render
1029
1033
   - set callbacks
1030
1034
   - cleanup
1031
1035
*/
1032
1036
 
1033
 
static void do_render(View3D *ogl_render_view3d, int anim, int force_dispwin)
 
1037
static void do_render(int anim)
1034
1038
{
1035
 
        
1036
 
        /* we set this flag to prevent renderwindow queue to execute another render */
1037
 
        R.flag= R_RENDERING;
1038
 
        G.afbreek= 0;
1039
 
 
1040
 
        if (G.displaymode == R_DISPLAYWIN || force_dispwin) {
1041
 
                RE_set_initrenderdisplay_callback(NULL);
1042
 
                RE_set_clearrenderdisplay_callback(renderwin_clear_display_cb);
1043
 
                RE_set_renderdisplay_callback(renderwin_progress_display_cb);
1044
 
 
1045
 
                renderwin_init_display_cb();
1046
 
        } 
1047
 
        else {
1048
 
                BIF_close_render_display();
1049
 
                RE_set_initrenderdisplay_callback(renderview_init_display_cb);
1050
 
                RE_set_clearrenderdisplay_callback(NULL);
1051
 
                RE_set_renderdisplay_callback(renderview_progress_display_cb);
1052
 
        }
1053
 
 
1054
 
        init_test_break_callback();
1055
 
        RE_set_test_break_callback(test_break);
1056
 
        
1057
 
        RE_set_timecursor_callback(set_timecursor);
1058
 
        RE_set_printrenderinfo_callback(printrenderinfo_cb);
1059
 
        
1060
 
        if (render_win) {
 
1039
        Render *re= RE_NewRender(G.scene->id.name);
 
1040
        unsigned int lay= G.scene->lay;
 
1041
        int scemode= G.scene->r.scemode;
 
1042
        
 
1043
        /* UGLY! we set this flag to prevent renderwindow queue to execute another render */
 
1044
        /* is reset in RE_BlenderFrame */
 
1045
        G.rendering= 1;
 
1046
 
 
1047
        /* set render callbacks, also starts ESC timer */
 
1048
        BIF_init_render_callbacks(re, 1);
 
1049
        
 
1050
        waitcursor(1);
 
1051
        if(render_win) 
1061
1052
                window_set_cursor(render_win->win, CURSOR_WAIT);
1062
 
                // when opening new window... not cross platform identical behaviour, so
1063
 
                // for now call it each time
1064
 
                // if(ogl_render_view3d) init_gl_stuff();
1065
 
        }
1066
 
        waitcursor(1);
1067
 
 
1068
 
        if(G.obedit && !(G.scene->r.scemode & R_OGL)) {
 
1053
        
 
1054
        if(G.obedit)
1069
1055
                exit_editmode(0);       /* 0 = no free data */
1070
 
        }
1071
 
 
1072
 
        if(anim) {
1073
 
                RE_animrender(ogl_render_view3d);
1074
 
        }
1075
 
        else {
1076
 
                RE_initrender(ogl_render_view3d);
1077
 
        }
1078
 
 
1079
 
        if (render_win) window_set_cursor(render_win->win, CURSOR_STD);
1080
 
 
 
1056
 
 
1057
        /* allow localview render for objects with lights in normal layers */
 
1058
        if(curarea->spacetype==SPACE_VIEW3D) {
 
1059
                if(G.vd->lay & 0xFF000000) {
 
1060
                        G.scene->lay |= G.vd->lay;
 
1061
                        G.scene->r.scemode |= R_SINGLE_LAYER;
 
1062
                }
 
1063
                else G.scene->lay= G.vd->lay;
 
1064
        }
 
1065
        
 
1066
        if(anim)
 
1067
                RE_BlenderAnim(re, G.scene, G.scene->r.sfra, G.scene->r.efra);
 
1068
        else
 
1069
                RE_BlenderFrame(re, G.scene, G.scene->r.cfra);
 
1070
 
 
1071
        /* restore local view exception */
 
1072
        G.scene->lay= lay;
 
1073
        G.scene->r.scemode= scemode;
 
1074
        
 
1075
        if(render_win) window_set_cursor(render_win->win, CURSOR_STD);
 
1076
        
1081
1077
        free_filesel_spec(G.scene->r.pic);
1082
1078
 
1083
1079
        G.afbreek= 0;
1084
 
        end_test_break_callback();
1085
 
        
1086
 
        /* in dispiew it will destroy the image otherwise
1087
 
           window_make_active() raises window at osx and sends redraws */
1088
 
        if(G.displaymode==R_DISPLAYWIN) {
1089
 
                mainwindow_make_active();
1090
 
        
1091
 
                /* after an envmap creation...  */
1092
 
                if(R.flag & R_REDRAW_PRV) {
1093
 
                        BIF_all_preview_changed();
1094
 
                }
1095
 
                allqueue(REDRAWBUTSSCENE, 0);   // visualize fbuf for example
1096
 
        }
1097
 
        
1098
 
        R.flag= 0;      // before scene update!
1099
 
        
 
1080
        BIF_end_render_callbacks();
 
1081
        
 
1082
        /* after an envmap creation...  */
 
1083
//              if(R.flag & R_REDRAW_PRV) {
 
1084
//                      BIF_preview_changed(ID_TE);
 
1085
//              }
 
1086
                
1100
1087
        scene_update_for_newframe(G.scene, G.scene->lay);       // no redraw needed, this restores to view as we left it
1101
1088
        
1102
 
        waitcursor(0);  // waitcursor checks rendering R.flag...
1103
 
}
1104
 
 
1105
 
/* finds area with a 'dispview' set */
1106
 
static ScrArea *find_dispimage_v3d(void)
1107
 
{
1108
 
        ScrArea *sa;
1109
 
        
1110
 
        for (sa= G.curscreen->areabase.first; sa; sa= sa->next) {
1111
 
                if (sa->spacetype==SPACE_VIEW3D) {
1112
 
                        View3D *vd= sa->spacedata.first;
1113
 
                        if (vd->flag & V3D_DISPIMAGE)
1114
 
                                return sa;
1115
 
                }
1116
 
        }
1117
 
        
1118
 
        return NULL;
1119
 
}
1120
 
 
1121
 
/* used for swapping with spare buffer, when images are different size */
1122
 
static void scalefastrect(unsigned int *recto, unsigned int *rectn, int oldx, int oldy, int newx, int newy)
1123
 
{
1124
 
        unsigned int *rect, *newrect;
1125
 
        int x, y;
1126
 
        int ofsx, ofsy, stepx, stepy;
1127
 
 
1128
 
        stepx = (int)((65536.0 * (oldx - 1.0) / (newx - 1.0)) + 0.5);
1129
 
        stepy = (int)((65536.0 * (oldy - 1.0) / (newy - 1.0)) + 0.5);
1130
 
        ofsy = 32768;
1131
 
        newrect= rectn;
1132
 
        
1133
 
        for (y = newy; y > 0 ; y--){
1134
 
                rect = recto;
1135
 
                rect += (ofsy >> 16) * oldx;
1136
 
                ofsy += stepy;
1137
 
                ofsx = 32768;
1138
 
                for (x = newx ; x>0 ; x--){
1139
 
                        *newrect++ = rect[ofsx >> 16];
1140
 
                        ofsx += stepx;
1141
 
                }
1142
 
        }
 
1089
        waitcursor(0);
 
1090
}
 
1091
 
 
1092
static void renderwin_store_spare(void)
 
1093
{
 
1094
        RenderResult rres;
 
1095
        
 
1096
        if(render_win==0 || render_win->storespare==0)
 
1097
                return;
 
1098
 
 
1099
        if(render_win->showspare) {
 
1100
                render_win->showspare= 0;
 
1101
                window_set_title(render_win->win, renderwin_get_title(1));
 
1102
        }
 
1103
        
 
1104
        BLI_strncpy(render_win->render_text_spare, render_win->render_text, RW_MAXTEXT);
 
1105
        
 
1106
        if(render_win->rectspare) MEM_freeN(render_win->rectspare);
 
1107
        render_win->rectspare= NULL;
 
1108
        if(render_win->rectsparef) MEM_freeN(render_win->rectsparef);
 
1109
        render_win->rectsparef= NULL;
 
1110
        
 
1111
        RE_GetResultImage(RE_GetRender(G.scene->id.name), &rres);
 
1112
        
 
1113
        if(rres.rect32)
 
1114
                render_win->rectspare= MEM_dupallocN(rres.rect32);
 
1115
        else if(rres.rectf)
 
1116
                render_win->rectsparef= MEM_dupallocN(rres.rectf);
 
1117
 
 
1118
        render_win->sparex= rres.rectx;
 
1119
        render_win->sparey= rres.recty;
1143
1120
}
1144
1121
 
1145
1122
/* -------------- API: externally called --------------- */
1146
1123
 
1147
 
/* not used anywhere ??? */
1148
 
#if 0
1149
 
void BIF_renderwin_make_active(void)
1150
 
{
1151
 
        if(render_win) {
1152
 
                window_make_active(render_win->win);
1153
 
                mywinset(2);
1154
 
        }
1155
 
}
1156
 
#endif
 
1124
static void error_cb(char *str){error(str);}
 
1125
static int esc_timer_set= 0;
 
1126
 
 
1127
/* set callbacks, exported to sequence render too. 
 
1128
   Only call in foreground (UI) renders. */
 
1129
 
 
1130
void BIF_init_render_callbacks(Render *re, int do_display)
 
1131
{
 
1132
        if(do_display) {
 
1133
                if(G.displaymode!=R_DISPLAYWIN) {
 
1134
                        if(render_win)
 
1135
                                BIF_close_render_display();
 
1136
                        imagewindow_render_callbacks(re);
 
1137
                }
 
1138
                else {
 
1139
                        RE_display_init_cb(re, renderwin_init_display_cb);
 
1140
                        RE_display_draw_cb(re, renderwin_progress_display_cb);
 
1141
                        RE_display_clear_cb(re, renderwin_clear_display_cb);
 
1142
                        RE_stats_draw_cb(re, renderwin_renderinfo_cb);
 
1143
                }
 
1144
        }
 
1145
        
 
1146
        RE_error_cb(re, error_cb);
 
1147
        
 
1148
        G.afbreek= 0;
 
1149
        if(render_win)
 
1150
                render_win->flags &= ~RW_FLAGS_ESCAPE;
 
1151
 
 
1152
        /* start esc timer. ensure it happens once only */
 
1153
        if(esc_timer_set==0)
 
1154
                init_test_break_callback();
 
1155
        esc_timer_set++;
 
1156
        
 
1157
        RE_test_break_cb(re, test_break);
 
1158
        RE_timecursor_cb(re, set_timecursor);
 
1159
        
 
1160
}
 
1161
 
 
1162
/* the init/end callbacks can be called multiple times (sequence render) */
 
1163
void BIF_end_render_callbacks(void)
 
1164
{
 
1165
        esc_timer_set--;
 
1166
        if(esc_timer_set==0) {
 
1167
                end_test_break_callback();
 
1168
                
 
1169
                if(render_win)
 
1170
                        mainwindow_make_active();
 
1171
        }
 
1172
}
1157
1173
 
1158
1174
/* set up display, render an image or scene */
1159
1175
void BIF_do_render(int anim)
1167
1183
                        slink_flag = 1;
1168
1184
                }
1169
1185
        }
1170
 
 
1171
 
        /* if start render in 3d win, use layer from window (e.g also local view) */
1172
 
        if(curarea && curarea->spacetype==SPACE_VIEW3D) {
1173
 
                int lay= G.scene->lay;
1174
 
                /*
1175
 
                 * if view is defined (might not be if called form script), check
1176
 
                 * and set layers
1177
 
                 */
1178
 
                if(G.vd) {
1179
 
                        if(G.vd->lay & 0xFF000000)      // localview
1180
 
                                G.scene->lay |= G.vd->lay;
1181
 
                        else
1182
 
                                G.scene->lay= G.vd->lay;
1183
 
                }
1184
 
                
1185
 
                do_render(NULL, anim, 0);
1186
 
                
1187
 
                G.scene->lay= lay;
 
1186
        
 
1187
        if(render_win && render_win->showspare)
 
1188
                renderwin_store_spare();
 
1189
 
 
1190
        do_render(anim);
 
1191
 
 
1192
        if(G.scene->use_nodes) {
 
1193
                allqueue(REDRAWNODE, 1);
 
1194
                allqueue(REDRAWIMAGE, 1);
1188
1195
        }
1189
 
        else do_render(NULL, anim, 0);
1190
 
 
1191
1196
        if (slink_flag) G.f |= G_DOSCRIPTLINKS;
1192
1197
        if (G.f & G_DOSCRIPTLINKS) BPY_do_all_scripts(SCRIPT_POSTRENDER);
1193
1198
}
1194
1199
 
1195
1200
/* set up display, render the current area view in an image */
1196
 
void BIF_do_ogl_render(View3D *ogl_render_view3d, int anim)
 
1201
/* the RE_Render is only used to make sure we got the picture in the result */
 
1202
void BIF_do_ogl_render(View3D *v3d, int anim)
1197
1203
{
1198
 
        G.scene->r.scemode |= R_OGL;
1199
 
        do_render(ogl_render_view3d, anim, 1);
1200
 
        G.scene->r.scemode &= ~R_OGL;
 
1204
        Render *re= RE_NewRender(G.scene->id.name);
 
1205
        RenderResult *rr;
 
1206
        int winx, winy;
 
1207
        
 
1208
        G.afbreek= 0;
 
1209
        init_test_break_callback();
 
1210
        
 
1211
        winx= (G.scene->r.size*G.scene->r.xsch)/100;
 
1212
        winy= (G.scene->r.size*G.scene->r.ysch)/100;
 
1213
        
 
1214
        RE_InitState(re, &G.scene->r, winx, winy, NULL);
 
1215
        
 
1216
        /* for now, result is defaulting to floats still... */
 
1217
        rr= RE_GetResult(re);
 
1218
        if(rr->rect32==NULL)
 
1219
                rr->rect32= MEM_mallocN(sizeof(int)*winx*winy, "32 bits rects");
 
1220
        
 
1221
        /* open window */
 
1222
        renderwin_init_display_cb(rr);
 
1223
        if(render_win)
 
1224
                render_win->flags &= ~RW_FLAGS_ESCAPE;
 
1225
 
 
1226
        init_gl_stuff();
 
1227
        
 
1228
        waitcursor(1);
 
1229
 
 
1230
        if(anim) {
 
1231
                bMovieHandle *mh= BKE_get_movie_handle(G.scene->r.imtype);
 
1232
                int cfrao= CFRA;
 
1233
                
 
1234
                if(BKE_imtype_is_movie(G.scene->r.imtype))
 
1235
                        mh->start_movie(&G.scene->r, winx, winy);
 
1236
                
 
1237
                for(CFRA= SFRA; CFRA<=EFRA; CFRA++) {
 
1238
                        /* user event can close window */
 
1239
                        if(render_win==NULL)
 
1240
                                break;
 
1241
                        drawview3d_render(v3d, winx, winy);
 
1242
                        glReadPixels(0, 0, winx, winy, GL_RGBA, GL_UNSIGNED_BYTE, rr->rect32);
 
1243
                        window_swap_buffers(render_win->win);
 
1244
                        
 
1245
                        if(BKE_imtype_is_movie(G.scene->r.imtype)) {
 
1246
                                mh->append_movie(CFRA, rr->rect32, winx, winy);
 
1247
                                printf("Append frame %d", G.scene->r.cfra);
 
1248
                        }
 
1249
                        else {
 
1250
                                ImBuf *ibuf= IMB_allocImBuf(winx, winy, G.scene->r.planes, 0, 0);
 
1251
                                char name[FILE_MAXDIR+FILE_MAXFILE];
 
1252
                                int ok;
 
1253
                                
 
1254
                                BKE_makepicstring(name, (G.scene->r.cfra));
 
1255
 
 
1256
                                ibuf->rect= rr->rect32;    
 
1257
                                ok= BKE_write_ibuf(ibuf, name, G.scene->r.imtype, G.scene->r.subimtype, G.scene->r.quality);
 
1258
                                
 
1259
                                if(ok==0) {
 
1260
                                        printf("Write error: cannot save %s\n", name);
 
1261
                                        break;
 
1262
                                }
 
1263
                                else printf("Saved: %s", name);
 
1264
                                
 
1265
                /* imbuf knows which rects are not part of ibuf */
 
1266
                                IMB_freeImBuf(ibuf);    
 
1267
                        }
 
1268
                        /* movie stats prints have no line break */
 
1269
                        printf("\n");
 
1270
                        
 
1271
                        if(test_break()) break;
 
1272
                }
 
1273
                
 
1274
                if(BKE_imtype_is_movie(G.scene->r.imtype))
 
1275
                        mh->end_movie();
 
1276
                
 
1277
                CFRA= cfrao;
 
1278
        }
 
1279
        else {
 
1280
                drawview3d_render(v3d, winx, winy);
 
1281
                glReadPixels(0, 0, winx, winy, GL_RGBA, GL_UNSIGNED_BYTE, rr->rect32);
 
1282
                window_swap_buffers(render_win->win);
 
1283
        }
 
1284
        
 
1285
        if(render_win)
 
1286
                renderwin_draw(render_win, 0);
 
1287
 
 
1288
        mainwindow_make_active();
 
1289
        
 
1290
        if(anim)
 
1291
                scene_update_for_newframe(G.scene, G.scene->lay);       // no redraw needed, this restores to view as we left it
 
1292
        
 
1293
        end_test_break_callback();
 
1294
        waitcursor(0);
1201
1295
}
1202
1296
 
1203
1297
void BIF_redraw_render_rect(void)
1204
1298
{
1205
 
        
1206
1299
        /* redraw */
1207
 
        if (G.displaymode == R_DISPLAYWIN) {
1208
 
                // don't open render_win if rendering has been
1209
 
            // canceled or the render_win has been actively closed
1210
 
                if (render_win) {
1211
 
                        renderwin_queue_redraw(render_win);
 
1300
        if (render_win) {
 
1301
                renderwin_queue_redraw(render_win);
 
1302
        }
 
1303
        else {
 
1304
                Image *ima = (Image *)find_id("IM", "Render Result");
 
1305
                if(ima && ima->ibuf) {
 
1306
                        IMB_freeImBuf(ima->ibuf);
 
1307
                        ima->ibuf= NULL;
 
1308
                        allqueue(REDRAWIMAGE, 0);
1212
1309
                }
1213
 
        } else {
1214
 
                renderview_init_display_cb();
1215
 
                renderview_progress_display_cb(0, R.recty-1, R.rectx, R.recty, R.rectot);
1216
1310
        }
1217
1311
}       
1218
1312
 
1219
1313
void BIF_swap_render_rects(void)
1220
1314
{
1221
 
        unsigned int *temp;
1222
 
 
1223
 
        if(R.rectspare==0) {
1224
 
                R.rectspare= (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
1225
 
                R.sparex= R.rectx;
1226
 
                R.sparey= R.recty;
1227
 
        }
1228
 
        else if(R.sparex!=R.rectx || R.sparey!=R.recty) {
1229
 
                temp= (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
1230
 
                                        
1231
 
                scalefastrect(R.rectspare, temp, R.sparex, R.sparey, R.rectx, R.recty);
1232
 
                MEM_freeN(R.rectspare);
1233
 
                R.rectspare= temp;
1234
 
                                        
1235
 
                R.sparex= R.rectx;
1236
 
                R.sparey= R.recty;
1237
 
        }
1238
 
        
1239
 
        temp= R.rectot;
1240
 
        R.rectot= R.rectspare;
1241
 
        R.rectspare= temp;
1242
 
        
1243
 
        if (G.displaymode == R_DISPLAYWIN) {
1244
 
                if (render_win) {
1245
 
                        char *tmp= render_win->render_text_spare;
1246
 
                        render_win->render_text_spare= render_win->render_text;
1247
 
                        render_win->render_text= tmp;
1248
 
                        
1249
 
                        window_set_title(render_win->win, renderwin_get_title(1));
1250
 
                        
1251
 
                }
1252
 
        }
 
1315
        RenderResult rres;
 
1316
        
 
1317
        if (render_win==NULL) return;
 
1318
        
 
1319
        render_win->storespare= 1;
 
1320
        render_win->showspare ^= 1;
 
1321
                
 
1322
        RE_GetResultImage(RE_GetRender(G.scene->id.name), &rres);
 
1323
                
 
1324
        if(render_win->sparex!=rres.rectx || render_win->sparey!=rres.recty) {
 
1325
                if(render_win->rectspare) MEM_freeN(render_win->rectspare);
 
1326
                render_win->rectspare= NULL;
 
1327
                if(render_win->rectsparef) MEM_freeN(render_win->rectsparef);
 
1328
                render_win->rectsparef= NULL;
 
1329
        }
 
1330
        
 
1331
        window_set_title(render_win->win, renderwin_get_title(1));
1253
1332
 
1254
1333
        /* redraw */
1255
1334
        BIF_redraw_render_rect();
 
1335
 
1256
1336
}                               
1257
1337
 
1258
1338
/* called from usiblender.c too, to free and close renderwin */
1259
1339
void BIF_close_render_display(void)
1260
1340
{
1261
1341
        if (render_win) {
1262
 
 
1263
1342
                if (render_win->info_text) MEM_freeN(render_win->info_text);
1264
1343
                if (render_win->render_text) MEM_freeN(render_win->render_text);
1265
1344
                if (render_win->render_text_spare) MEM_freeN(render_win->render_text_spare);
1266
 
 
 
1345
                if (render_win->rectspare) MEM_freeN(render_win->rectspare);
 
1346
                if (render_win->rectsparef) MEM_freeN(render_win->rectsparef);
 
1347
                        
1267
1348
                window_destroy(render_win->win); /* ghost close window */
1268
1349
                MEM_freeN(render_win);
1269
1350
 
1275
1356
/* typical with F11 key, show image or hide/close */
1276
1357
void BIF_toggle_render_display(void) 
1277
1358
{
1278
 
        ScrArea *sa= find_dispimage_v3d();
1279
1359
        
1280
 
        if(R.rectot==NULL);             // do nothing
1281
 
        else if (render_win && G.displaymode==R_DISPLAYWIN) {
1282
 
                if(render_win->active) {
1283
 
                        mainwindow_raise();
1284
 
                        mainwindow_make_active();
1285
 
                        render_win->active= 0;
1286
 
                }
 
1360
        if (G.displaymode!=R_DISPLAYWIN) {
 
1361
                imagewindow_toggle_render();
 
1362
        }
 
1363
        else {
 
1364
                if (render_win) {
 
1365
                        if(render_win->active) {
 
1366
                                mainwindow_raise();
 
1367
                                mainwindow_make_active();
 
1368
                                render_win->active= 0;
 
1369
                        }
 
1370
                        else {
 
1371
                                window_raise(render_win->win);
 
1372
                                window_make_active(render_win->win);
 
1373
                                render_win->active= 1;
 
1374
                        }
 
1375
                } 
1287
1376
                else {
1288
 
                        window_raise(render_win->win);
1289
 
                        window_make_active(render_win->win);
1290
 
                        render_win->active= 1;
1291
 
                }
1292
 
        } 
1293
 
        else if (sa && G.displaymode==R_DISPLAYVIEW) {
1294
 
                View3D *vd= sa->spacedata.first;
1295
 
                vd->flag &= ~V3D_DISPIMAGE;
1296
 
                scrarea_queue_winredraw(sa);
1297
 
        } 
1298
 
        else {
1299
 
                if (G.displaymode == R_DISPLAYWIN) {
1300
 
                        renderwin_init_display_cb();
1301
 
                } else {
1302
 
                        if (render_win) {
1303
 
                                BIF_close_render_display();
1304
 
                        }
1305
 
                        renderview_init_display_cb();
1306
 
                        renderview_progress_display_cb(0, R.recty-1, R.rectx, R.recty, R.rectot);
 
1377
                        RenderResult *rr= RE_GetResult(RE_GetRender(G.scene->id.name));
 
1378
                        if(rr) renderwin_init_display_cb(rr);
1307
1379
                }
1308
1380
        }
1309
1381
}