2.5 - Silencing various compiler warnings (mingw)
[blender-staging.git] / source / blender / editors / preview / previewrender.c
1 /* 
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) Blender Foundation.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 /* global includes */
31
32 #include <stdlib.h>
33 #include <math.h>
34 #include <string.h>
35
36 #ifndef WIN32
37 #include <unistd.h>
38 #else
39 #include <io.h>
40 #endif   
41 #include "MEM_guardedalloc.h"
42
43 #include "BLO_readfile.h" 
44
45 #include "BLI_arithb.h"
46 #include "BLI_blenlib.h"
47 #include "BLI_threads.h"
48
49 #include "DNA_texture_types.h"
50 #include "DNA_world_types.h"
51 #include "DNA_camera_types.h"
52 #include "DNA_image_types.h"
53 #include "DNA_material_types.h"
54 #include "DNA_node_types.h"
55 #include "DNA_object_types.h"
56 #include "DNA_lamp_types.h"
57 #include "DNA_space_types.h"
58 #include "DNA_view3d_types.h"
59 #include "DNA_scene_types.h"
60 #include "DNA_screen_types.h"
61
62 #include "BKE_context.h"
63 #include "BKE_depsgraph.h"
64 #include "BKE_global.h"
65 #include "BKE_image.h"
66 #include "BKE_icons.h"
67 #include "BKE_library.h"
68 #include "BKE_main.h"
69 #include "BKE_texture.h"
70 #include "BKE_material.h"
71 #include "BKE_node.h"
72 #include "BKE_world.h"
73 #include "BKE_texture.h"
74 #include "BKE_utildefines.h"
75
76 #include "IMB_imbuf.h"
77 #include "IMB_imbuf_types.h"
78
79 #include "BIF_gl.h"
80 #include "BIF_glutil.h"
81
82 #include "PIL_time.h"
83
84 #include "RE_pipeline.h"
85
86 #include "GPU_material.h"
87
88 #include "WM_api.h"
89 #include "WM_types.h"
90
91 #include "ED_anim_api.h"
92 #include "ED_previewrender.h"
93 #include "ED_view3d.h"
94
95 #include "UI_interface.h"
96
97 #include "previewrender_intern.h"
98
99 #define PR_XMIN         10
100 #define PR_YMIN         5
101 #define PR_XMAX         200
102 #define PR_YMAX         195
103
104 /* XXX */
105 static int qtest() {return 0;}
106 /* XXX */
107
108 typedef struct ShaderPreview {
109         /* from wmJob */
110         void *owner;
111         short *stop, *do_update;
112         
113         Scene *scene;
114         ID *id;
115         
116         int sizex, sizey;
117         int *pr_rect;
118         int pr_method;
119         
120 } ShaderPreview;
121
122
123
124 /* unused now */
125 void draw_tex_crop(Tex *tex)
126 {
127         rcti rct;
128         int ret= 0;
129         
130         if(tex==0) return;
131         
132         if(tex->type==TEX_IMAGE) {
133                 if(tex->cropxmin==0.0f) ret++;
134                 if(tex->cropymin==0.0f) ret++;
135                 if(tex->cropxmax==1.0f) ret++;
136                 if(tex->cropymax==1.0f) ret++;
137                 if(ret==4) return;
138                 
139                 rct.xmin= PR_XMIN+2+tex->cropxmin*(PR_XMAX-PR_XMIN-4);
140                 rct.xmax= PR_XMIN+2+tex->cropxmax*(PR_XMAX-PR_XMIN-4);
141                 rct.ymin= PR_YMIN+2+tex->cropymin*(PR_YMAX-PR_YMIN-4);
142                 rct.ymax= PR_YMIN+2+tex->cropymax*(PR_YMAX-PR_YMIN-4);
143
144                 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 
145
146                 glColor3ub(0, 0, 0);
147                 glRecti(rct.xmin+1,  rct.ymin-1,  rct.xmax+1,  rct.ymax-1); 
148
149                 glColor3ub(255, 255, 255);
150                 glRecti(rct.xmin,  rct.ymin,  rct.xmax,  rct.ymax);
151
152                 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);                      
153         }
154         
155 }
156
157 /* temporal abuse; if id_code is -1 it only does texture.... solve! */
158 void BIF_preview_changed(short id_code)
159 {
160 #if 0   
161         ScrArea *sa;
162         
163         for(sa= G.curscreen->areabase.first; sa; sa= sa->next) {
164                 if(sa->spacetype==SPACE_BUTS) {
165                         SpaceButs *sbuts= sa->spacedata.first;
166                         if(sbuts->mainb==CONTEXT_SHADING) {
167                                 int tab= sbuts->tab[CONTEXT_SHADING];
168                                 if(tab==TAB_SHADING_MAT && (id_code==ID_MA || id_code==ID_TE)) {
169                                         if (sbuts->ri) sbuts->ri->curtile= 0;
170                                         addafterqueue(sa->win, RENDERPREVIEW, 1);
171                                 }
172                                 else if(tab==TAB_SHADING_TEX && (id_code==ID_TE || id_code==-1)) {
173                                         if (sbuts->ri) sbuts->ri->curtile= 0;
174                                         addafterqueue(sa->win, RENDERPREVIEW, 1);
175                                 }
176                                 else if(tab==TAB_SHADING_LAMP && (id_code==ID_LA || id_code==ID_TE)) {
177                                         if (sbuts->ri) sbuts->ri->curtile= 0;
178                                         addafterqueue(sa->win, RENDERPREVIEW, 1);
179                                 }
180                                 else if(tab==TAB_SHADING_WORLD && (id_code==ID_WO || id_code==ID_TE)) {
181                                         if (sbuts->ri) sbuts->ri->curtile= 0;
182                                         addafterqueue(sa->win, RENDERPREVIEW, 1);
183                                 }
184                         }
185                         else if (sbuts->ri) 
186                                 sbuts->ri->curtile= 0;  /* ensure changes always result in re-render when context is restored */
187                 }
188                 else if(sa->spacetype==SPACE_NODE) {
189                         SpaceNode *snode= sa->spacedata.first;
190                         if(snode->treetype==NTREE_SHADER && (id_code==ID_MA || id_code==ID_TE)) {
191                                 snode_tag_dirty(snode);
192                         }
193                 }
194                 else if(sa->spacetype==SPACE_VIEW3D) {
195                         View3D *vd= sa->spacedata.first;
196                         /* if is has a renderinfo, we consider that reason for signalling */
197                         if (vd->ri) {
198                                 vd->ri->curtile= 0;
199                                 addafterqueue(sa->win, RENDERPREVIEW, 1);
200                         }
201                 }
202         }
203
204         if(ELEM4(id_code, ID_MA, ID_TE, ID_LA, ID_WO)) {
205                 Object *ob;
206                 Material *ma;
207
208                 if(id_code == ID_WO) {
209                         for(ma=G.main->mat.first; ma; ma=ma->id.next) {
210                                 if(ma->gpumaterial.first) {
211                                         GPU_material_free(ma);
212                                 }
213                         }
214                 }
215                 else if(id_code == ID_LA) {
216                         for(ob=G.main->object.first; ob; ob=ob->id.next) {
217                                 if(ob->gpulamp.first) {
218                                         GPU_lamp_free(ob);
219                                 }
220                         }
221
222                         for(ma=G.main->mat.first; ma; ma=ma->id.next) {
223                                 if(ma->gpumaterial.first) {
224                                         GPU_material_free(ma);
225                                 }
226                         }
227                 } else if(OBACT) {
228                         Object *ob = OBACT;
229
230                         ma= give_current_material(ob, ob->actcol);
231                         if(ma && ma->gpumaterial.first) {
232                                 GPU_material_free(ma);
233                         }
234                 }
235         }
236 #endif
237 }
238
239 /* *************************** Preview for buttons *********************** */
240
241 static Main *pr_main= NULL;
242
243 void ED_preview_init_dbase(void)
244 {
245         BlendFileData *bfd;
246         extern int datatoc_preview_blend_size;
247         extern char datatoc_preview_blend[];
248         
249         G.fileflags |= G_FILE_NO_UI;
250         bfd= BLO_read_from_memory(datatoc_preview_blend, datatoc_preview_blend_size, NULL);
251         if (bfd) {
252                 pr_main= bfd->main;
253                 
254                 MEM_freeN(bfd);
255         }
256         G.fileflags &= ~G_FILE_NO_UI;
257 }
258
259 void ED_preview_free_dbase(void)
260 {
261         if(pr_main)
262                 free_main(pr_main);
263 }
264
265 static Object *find_object(ListBase *lb, const char *name)
266 {
267         Object *ob;
268         for(ob= lb->first; ob; ob= ob->id.next)
269                 if(strcmp(ob->id.name+2, name)==0)
270                         break;
271         return ob;
272 }
273
274 /* call this with a pointer to initialize preview scene */
275 /* call this with NULL to restore assigned ID pointers in preview scene */
276 static Scene *preview_prepare_scene(Scene *scene, int id_type, ShaderPreview *sp)
277 {
278         Scene *sce;
279         Base *base;
280         ID *id= sp?sp->id:NULL;
281         
282         if(pr_main==NULL) return NULL;
283         
284         sce= pr_main->scene.first;
285         if(sce) {
286                 /* this flag tells render to not execute depsgraph or ipos etc */
287                 sce->r.scemode |= R_PREVIEWBUTS;
288                 /* set world always back, is used now */
289                 sce->world= pr_main->world.first;
290                 /* now: exposure copy */
291                 if(scene->world) {
292                         sce->world->exp= scene->world->exp;
293                         sce->world->range= scene->world->range;
294                 }
295                 
296                 sce->r.cfra= scene->r.cfra;
297                 
298                 if(id_type==ID_MA) {
299                         Material *mat= (Material *)id;
300                         
301                         if(id) {
302                                 init_render_material(mat, 0, NULL);             /* call that retrieves mode_l */
303                                 end_render_material(mat);
304                                 
305                                 /* turn on raytracing if needed */
306                                 if(mat->mode_l & (MA_RAYTRANSP|MA_RAYMIRROR))
307                                         sce->r.mode |= R_RAYTRACE;
308                                 if(mat->sss_flag & MA_DIFF_SSS)
309                                         sce->r.mode |= R_SSS;
310                                 
311                                 /* turn off fake shadows if needed */
312                                 /* this only works in a specific case where the preview.blend contains
313                                  * an object starting with 'c' which has a material linked to it (not the obdata)
314                                  * and that material has a fake shadow texture in the active texture slot */
315                                 for(base= sce->base.first; base; base= base->next) {
316                                         if(base->object->id.name[2]=='c') {
317                                                 Material *shadmat= give_current_material(base->object, base->object->actcol);
318                                                 if(shadmat) {
319                                                         if (mat->mode & MA_SHADBUF) shadmat->septex = 0;
320                                                         else shadmat->septex |= 1;
321                                                 }
322                                         }
323                                 }
324
325                                 
326                                 if(sp->pr_method==PR_ICON_RENDER) {
327                                         if (mat->material_type == MA_TYPE_HALO) {
328                                                 sce->lay= 1<<MA_FLAT;
329                                         } 
330                                         else {
331                                                 sce->lay= 1<<MA_SPHERE_A;
332                                         }
333                                 }
334                                 else {
335                                         sce->lay= 1<<mat->pr_type;
336                                         if(mat->nodetree)
337                                                 ntreeInitPreview(mat->nodetree, sp->sizex, sp->sizey);
338                                 }
339                         }
340                         else {
341                                 sce->r.mode &= ~(R_OSA|R_RAYTRACE|R_SSS);
342                         }
343                         
344                         for(base= sce->base.first; base; base= base->next) {
345                                 if(base->object->id.name[2]=='p') {
346                                         if(ELEM4(base->object->type, OB_MESH, OB_CURVE, OB_SURF, OB_MBALL))
347                                                 assign_material(base->object, mat, base->object->actcol);
348                                 }
349                         }
350                 }
351                 else if(id_type==ID_TE) {
352                         Tex *tex= (Tex *)id;
353                         
354                         sce->lay= 1<<MA_TEXTURE;
355                         
356                         for(base= sce->base.first; base; base= base->next) {
357                                 if(base->object->id.name[2]=='t') {
358                                         Material *mat= give_current_material(base->object, base->object->actcol);
359                                         if(mat && mat->mtex[0]) {
360                                                 mat->mtex[0]->tex= tex;
361                                                 /* show alpha in this case */
362                                                 if(tex==NULL || (tex->flag & TEX_PRV_ALPHA)) {
363                                                         mat->mtex[0]->mapto |= MAP_ALPHA;
364                                                         mat->alpha= 0.0f;
365                                                 }
366                                                 else {
367                                                         mat->mtex[0]->mapto &= ~MAP_ALPHA;
368                                                         mat->alpha= 1.0f;
369                                                 }
370                                         }
371                                 }
372                         }
373                 }
374                 else if(id_type==ID_LA) {
375                         Lamp *la= (Lamp *)id;
376                         
377                         if(la && la->type==LA_SUN && (la->sun_effect_type & LA_SUN_EFFECT_SKY)) {
378                                 sce->lay= 1<<MA_ATMOS;
379                                 sce->world= scene->world;
380                                 sce->camera= (Object *)find_object(&pr_main->object, "CameraAtmo");
381                         }
382                         else {
383                                 sce->lay= 1<<MA_LAMP;
384                                 sce->world= NULL;
385                                 sce->camera= (Object *)find_object(&pr_main->object, "Camera");
386                         }
387                         sce->r.mode &= ~R_SHADOW;
388                         
389                         for(base= sce->base.first; base; base= base->next) {
390                                 if(base->object->id.name[2]=='p') {
391                                         if(base->object->type==OB_LAMP)
392                                                 base->object->data= la;
393                                 }
394                         }
395                 }
396                 else if(id_type==ID_WO) {
397                         sce->lay= 1<<MA_SKY;
398                         sce->world= (World *)id;
399                 }
400                 
401                 return sce;
402         }
403         
404         return NULL;
405 }
406
407
408 /* new UI convention: draw is in pixel space already. */
409 /* uses ROUNDBOX button in block to get the rect */
410 void ED_preview_draw(const bContext *C, void *idp, rcti *rect)
411 {
412         if(idp) {
413                 ScrArea *sa= CTX_wm_area(C);
414                 SpaceButs *sbuts= sa->spacedata.first;
415                 RenderResult rres;
416                 int newx= rect->xmax-rect->xmin, newy= rect->ymax-rect->ymin;
417                 int ok= 0;
418                 char name[32];
419                 
420                 sprintf(name, "Preview %p", sa);
421                 BLI_lock_malloc_thread();
422                 RE_GetResultImage(RE_GetRender(name), &rres);
423
424                 if(rres.rectf) {
425                         
426                         if( ABS(rres.rectx-newx)<2 && ABS(rres.recty-newy)<2 ) {
427                                 /* correct size, then black outline matches */
428                                 rect->xmax= rect->xmin + rres.rectx;
429                                 rect->ymax= rect->ymin + rres.recty;
430                         
431                                 glaDrawPixelsSafe(rect->xmin, rect->ymin, rres.rectx, rres.recty, rres.rectx, GL_RGBA, GL_FLOAT, rres.rectf);
432                                 ok= 1;
433                         }
434                 }
435                 BLI_unlock_malloc_thread();
436
437                 /* check for spacetype... */
438                 if(sbuts->spacetype==SPACE_BUTS && sbuts->preview) {
439                         sbuts->preview= 0;
440                         ok= 0;
441                 }
442                 
443                 if(ok==0) {
444                         ED_preview_shader_job(C, sa, idp, newx, newy);
445                 }
446         }       
447 }
448
449 /* *************************** Preview for 3d window *********************** */
450
451 void view3d_previewrender_progress(RenderResult *rr, volatile rcti *renrect)
452 {
453 //      ScrArea *sa= NULL; // XXX
454 //      View3D *v3d= NULL; // XXX
455         RenderLayer *rl;
456         int ofsx=0, ofsy=0;
457         
458         if(renrect) return;
459         
460         rl= rr->layers.first;
461         
462         /* this case is when we render envmaps... */
463 //      if(rr->rectx > v3d->ri->pr_rectx || rr->recty > v3d->ri->pr_recty)
464 //              return;
465         
466 //      ofsx= v3d->ri->disprect.xmin + rr->tilerect.xmin;
467 //      ofsy= v3d->ri->disprect.ymin + rr->tilerect.ymin;
468         
469         glDrawBuffer(GL_FRONT);
470 //      glaDefine2DArea(&sa->winrct);
471         glaDrawPixelsSafe_to32(ofsx, ofsy, rr->rectx, rr->recty, rr->rectx, rl->rectf);
472         bglFlush();
473         glDrawBuffer(GL_BACK);
474
475 }
476
477 void BIF_view3d_previewrender_signal(ScrArea *sa, short signal)
478 {
479 #if 0
480         View3D *v3d= sa->spacedata.first;
481         
482         /* this can be called from other window... solve! */
483         if(sa->spacetype!=SPACE_VIEW3D)
484                 return; // XXX
485            
486         if(v3d && v3d->ri) {
487                 RenderInfo *ri= v3d->ri;
488                 ri->status &= ~signal;
489                 ri->curtile= 0;
490                 //printf("preview signal %d\n", signal);
491                 if(ri->re && (signal & PR_DBASE))
492                         RE_Database_Free(ri->re);
493
494 //              addafterqueue(sa->win, RENDERPREVIEW, 1);
495         }
496 #endif
497 }
498
499 void BIF_view3d_previewrender_free(View3D *v3d)
500 {
501 #if 0
502         if(v3d->ri) {
503                 RenderInfo *ri= v3d->ri;
504                 if(ri->re) {
505 //                      printf("free render\n");
506                         RE_Database_Free(ri->re);
507                         RE_FreeRender(ri->re);
508                         ri->re= NULL;
509                 }
510                 if (v3d->ri->rect) MEM_freeN(v3d->ri->rect);
511                 MEM_freeN(v3d->ri);
512                 v3d->ri= NULL;
513         }
514 #endif
515 }
516
517 /* returns 1 if OK, do not call while in panel space!  */
518 static int view3d_previewrender_get_rects(ScrArea *sa, rctf *viewplane, RenderInfo *ri, float *clipsta, float *clipend, int *ortho, float *pixsize)
519 {
520         View3D *v3d= NULL; // XXX
521         RegionView3D *rv3d= NULL; // XXX
522         int rectx, recty;
523 //      uiBlock *block;
524         
525 //      block= uiFindOpenPanelBlockName(&sa->uiblocks, "Preview");
526 //      if(block==NULL) return 0;
527         
528         /* calculate preview rect size */
529 //      BLI_init_rctf(viewplane, 15.0f, (block->maxx - block->minx)-15.0f, 15.0f, (block->maxy - block->miny)-15.0f);
530 //      uiPanelPush(block);
531 //      ui_graphics_to_window_rct(sa->win, viewplane, &ri->disprect);
532 //      uiPanelPop(block);
533         
534         /* correction for gla draw */
535 //      BLI_translate_rcti(&ri->disprect, -sa->winrct.xmin, -sa->winrct.ymin);
536         
537         *ortho= get_view3d_viewplane(v3d, rv3d, sa->winx, sa->winy, viewplane, clipsta, clipend, pixsize);
538
539         rectx= ri->disprect.xmax - ri->disprect.xmin;
540         recty= ri->disprect.ymax - ri->disprect.ymin;
541         
542         if(rectx<4 || recty<4) return 0;
543         
544         if(ri->rect && (rectx!=ri->pr_rectx || recty!=ri->pr_recty)) {
545                 MEM_freeN(ri->rect);
546                 ri->rect= NULL;
547                 ri->curtile= 0;
548                 printf("changed size\n");
549         }
550         ri->pr_rectx= rectx;
551         ri->pr_recty= recty;
552         
553         return 1;
554 }
555
556 /* called before a panel gets moved/scaled, makes sure we can see through */
557 void BIF_view3d_previewrender_clear(ScrArea *sa)
558 {
559 #if 0
560         View3D *v3d= sa->spacedata.first;
561
562         if(v3d->ri) {
563                 RenderInfo *ri= v3d->ri;
564                 ri->curtile= 0;
565                 if(ri->rect)
566                         MEM_freeN(ri->rect);
567                 ri->rect= NULL;
568         }
569 #endif
570 }
571
572 /* afterqueue call */
573 void BIF_view3d_previewrender(Scene *scene, ScrArea *sa)
574 {
575         bContext *C= NULL;
576         View3D *v3d= sa->spacedata.first;
577         RegionView3D *rv3d= NULL; // XXX
578         Render *re;
579         RenderInfo *ri=NULL;    /* preview struct! */
580         RenderStats *rstats;
581         RenderData rdata;
582         rctf viewplane;
583         float clipsta, clipend, pixsize;
584         int orth;
585         
586         /* first get the render info right */
587 //      if (!v3d->ri) {
588 //              ri= v3d->ri= MEM_callocN(sizeof(RenderInfo), "butsrenderinfo");
589 //              ri->tottile= 10000;
590 //      }
591 //      ri= v3d->ri;
592         
593         if(0==view3d_previewrender_get_rects(sa, &viewplane, ri, &clipsta, &clipend, &orth, &pixsize))
594                 return;
595         
596         /* render is finished, so return */
597         if(ri->tottile && ri->curtile>=ri->tottile) return;
598
599         /* or return with a new event */
600         if(qtest()) {
601 //              addafterqueue(sa->win, RENDERPREVIEW, 1);
602                 return;
603         }
604         //printf("Enter previewrender\n");
605         /* ok, are we rendering all over? */
606         if(ri->re==NULL) {
607                 char name[32];
608                 
609                 ri->status= 0;
610                 
611                 sprintf(name, "View3dPreview %p", sa);
612                 re= ri->re= RE_NewRender(name);
613                 //RE_display_draw_cb(re, view3d_previewrender_progress);
614                 //RE_stats_draw_cb(re, view3d_previewrender_stats);
615                 //RE_test_break_cb(re, qtest);
616                 
617                 /* no osa, blur, seq, layers, etc for preview render */
618                 rdata= scene->r;
619                 rdata.mode &= ~(R_OSA|R_MBLUR);
620                 rdata.scemode &= ~(R_DOSEQ|R_DOCOMP|R_FREE_IMAGE);
621                 rdata.layers.first= rdata.layers.last= NULL;
622                 rdata.renderer= R_INTERN;
623                  
624                 RE_InitState(re, NULL, &rdata, sa->winx, sa->winy, &ri->disprect);
625         
626                 if(orth)
627                         RE_SetOrtho(re, &viewplane, clipsta, clipend);
628                 else
629                         RE_SetWindow(re, &viewplane, clipsta, clipend);
630                 RE_SetPixelSize(re, pixsize);
631                 
632                 /* until here are no escapes */
633                 ri->status |= PR_DISPRECT;
634                 ri->curtile= 0;
635                 //printf("new render\n");
636         }
637
638         re= ri->re;
639         
640         PIL_sleep_ms(100);      /* wait 0.1 second if theres really no event... */
641         if(qtest()==0)  {
642                 
643                 /* check status */
644                 if((ri->status & PR_DISPRECT)==0) {
645                         RE_SetDispRect(ri->re, &ri->disprect);
646                         if(orth)
647                                 RE_SetOrtho(ri->re, &viewplane, clipsta, clipend);
648                         else
649                                 RE_SetWindow(ri->re, &viewplane, clipsta, clipend);
650                         RE_SetPixelSize(re, pixsize);
651                         ri->status |= PR_DISPRECT;
652                         ri->curtile= 0;
653                         //printf("disprect update\n");
654                 }
655                 if((ri->status & PR_DBASE)==0) {
656                         unsigned int lay= scene->lay;
657                         
658                         RE_SetView(re, rv3d->viewmat);
659                         
660                         /* allow localview render for objects with lights in normal layers */
661                         if(v3d->lay & 0xFF000000)
662                                 scene->lay |= v3d->lay;
663                         else scene->lay= v3d->lay;
664                         
665                         RE_Database_FromScene(re, scene, 0);            // 0= dont use camera view
666                         scene->lay= lay;
667                         
668                         rstats= RE_GetStats(re);
669                         if(rstats->convertdone) 
670                                 ri->status |= PR_DBASE|PR_PROJECTED|PR_ROTATED;
671                         ri->curtile= 0;
672                         
673                         /* database can have created render-resol data... */
674                         if(rstats->convertdone) 
675                                 ED_anim_dag_flush_update(C); // <--- only current scene XXX
676                         
677                         //printf("dbase update\n");
678                 }
679                 if((ri->status & PR_PROJECTED)==0) {
680                         if(ri->status & PR_DBASE) {
681                                 if(orth)
682                                         RE_SetOrtho(ri->re, &viewplane, clipsta, clipend);
683                                 else
684                                         RE_SetWindow(ri->re, &viewplane, clipsta, clipend);
685                                 RE_DataBase_ApplyWindow(re);
686                                 ri->status |= PR_PROJECTED;
687                         }
688                         ri->curtile= 0;
689                         //printf("project update\n");
690                 }
691         
692                 /* OK, can we enter render code? */
693                 if(ri->status==(PR_DISPRECT|PR_DBASE|PR_PROJECTED|PR_ROTATED)) {
694                         //printf("curtile %d tottile %d\n", ri->curtile, ri->tottile);
695                         RE_TileProcessor(ri->re, ri->curtile, 0);
696         
697                         if(ri->rect==NULL)
698                                 ri->rect= MEM_mallocN(sizeof(int)*ri->pr_rectx*ri->pr_recty, "preview view3d rect");
699                         
700                         RE_ResultGet32(ri->re, ri->rect);
701                 }
702                 
703                 rstats= RE_GetStats(ri->re);
704 //              if(rstats->totpart==rstats->partsdone && rstats->partsdone)
705 //                      addqueue(sa->win, REDRAW, 1);
706 //              else
707 //                      addafterqueue(sa->win, RENDERPREVIEW, 1);
708                 
709                 ri->curtile= rstats->partsdone;
710                 ri->tottile= rstats->totpart;
711         }
712         else {
713 //              addafterqueue(sa->win, RENDERPREVIEW, 1);
714         }
715         
716         //printf("\n");
717 }
718
719 /* in panel space! */
720 static void view3d_previewdraw_rect(ScrArea *sa, uiBlock *block, RenderInfo *ri)
721 {
722 //      rctf dispf;
723         
724         if(ri->rect==NULL)
725                 return;
726         
727 //      BLI_init_rctf(&dispf, 15.0f, (block->maxx - block->minx)-15.0f, 15.0f, (block->maxy - block->miny)-15.0f);
728 //      ui_graphics_to_window_rct(sa->win, &dispf, &ri->disprect);
729
730         /* correction for gla draw */
731 //      BLI_translate_rcti(&ri->disprect, -sa->winrct.xmin, -sa->winrct.ymin);
732         
733         /* when panel scale changed, free rect */
734         if(ri->disprect.xmax-ri->disprect.xmin != ri->pr_rectx ||
735            ri->disprect.ymax-ri->disprect.ymin != ri->pr_recty) {
736                 MEM_freeN(ri->rect);
737                 ri->rect= NULL;
738         }
739         else {
740 //              glaDefine2DArea(&sa->winrct);
741                 glaDrawPixelsSafe(ri->disprect.xmin, ri->disprect.ymin, ri->pr_rectx, ri->pr_recty, ri->pr_rectx, GL_RGBA, GL_UNSIGNED_BYTE, ri->rect);
742         }       
743 }
744
745 /* is panel callback, supposed to be called with correct panel offset matrix */
746 void BIF_view3d_previewdraw(struct ScrArea *sa, struct uiBlock *block)
747 {
748         RegionView3D *rv3d= NULL;
749
750 //      if (v3d->ri==NULL || v3d->ri->rect==NULL) 
751 //              addafterqueue(sa->win, RENDERPREVIEW, 1);
752 //      else {
753                 view3d_previewdraw_rect(sa, block, rv3d->ri);
754 //              if(v3d->ri->curtile==0) 
755 //                      addafterqueue(sa->win, RENDERPREVIEW, 1);
756 //      }
757 }
758
759
760 /* **************************** New preview system ****************** */
761
762 /* inside thread, called by renderer, sets job update value */
763 static void shader_preview_draw(void *spv, RenderResult *rr, volatile struct rcti *rect)
764 {
765         ShaderPreview *sp= spv;
766         
767         *(sp->do_update)= 1;
768 }
769
770 /* called by renderer, checks job value */
771 static int shader_preview_break(void *spv)
772 {
773         ShaderPreview *sp= spv;
774         
775         return *(sp->stop);
776 }
777
778 /* outside thread, called before redraw notifiers, it moves finished preview over */
779 static void shader_preview_updatejob(void *spv)
780 {
781 //      ShaderPreview *sp= spv;
782         
783 }
784
785 /* runs inside thread for material, in foreground for icons */
786 static void shader_preview_startjob(void *customdata, short *stop, short *do_update)
787 {
788         ShaderPreview *sp= customdata;
789         Render *re;
790         Scene *sce;
791         float oldlens;
792         char name [32];
793
794         sp->stop= stop;
795         sp->do_update= do_update;
796         
797         /* get the stuff from the builtin preview dbase */
798         sce= preview_prepare_scene(sp->scene, GS(sp->id->name), sp);
799         if(sce==NULL) return;
800         
801         sprintf(name, "Preview %p", sp->owner);
802         re= RE_GetRender(name);
803         
804         /* full refreshed render from first tile */
805         if(re==NULL)
806                 re= RE_NewRender(name);
807                 
808         /* sce->r gets copied in RE_InitState! */
809         if(sp->pr_method==PR_DO_RENDER) {
810                 sce->r.scemode |= R_NODE_PREVIEW;
811                 sce->r.scemode &= ~R_NO_IMAGE_LOAD;
812                 sce->r.mode |= R_OSA;
813         }
814         else {  /* PR_ICON_RENDER */
815                 sce->r.scemode &= ~R_NODE_PREVIEW;
816                 sce->r.scemode |= R_NO_IMAGE_LOAD;
817         }
818
819         /* allocates or re-uses render result */
820         RE_InitState(re, NULL, &sce->r, sp->sizex, sp->sizey, NULL);
821
822         /* callbacs are cleared on GetRender() */
823         if(sp->pr_method==PR_DO_RENDER) {
824                 RE_display_draw_cb(re, sp, shader_preview_draw);
825                 RE_test_break_cb(re, sp, shader_preview_break);
826         }
827         /* lens adjust */
828         oldlens= ((Camera *)sce->camera->data)->lens;
829         if(sp->sizex > sp->sizey)
830                 ((Camera *)sce->camera->data)->lens *= (float)sp->sizey/(float)sp->sizex;
831
832         /* entire cycle for render engine */
833         RE_SetCamera(re, sce->camera);
834         RE_Database_FromScene(re, sce, 1);
835         RE_TileProcessor(re, 0, 1);     // actual render engine
836         RE_Database_Free(re);
837
838         ((Camera *)sce->camera->data)->lens= oldlens;
839         *do_update= 1;
840
841         /* handle results */
842         if(sp->pr_method==PR_ICON_RENDER) {
843                 if(sp->pr_rect)
844                         RE_ResultGet32(re, sp->pr_rect);
845         }
846         else {
847                 /* validate owner */
848                 //if(ri->rect==NULL)
849                 //      ri->rect= MEM_mallocN(sizeof(int)*ri->pr_rectx*ri->pr_recty, "BIF_previewrender");
850                 //RE_ResultGet32(re, ri->rect);
851         }
852
853         /* unassign the pointers, reset vars */
854         preview_prepare_scene(sp->scene, GS(sp->id->name), NULL);
855
856 }
857
858 static void shader_preview_free(void *customdata)
859 {
860         ShaderPreview *sp= customdata;
861         
862         MEM_freeN(sp);
863 }
864
865 void ED_preview_shader_job(const bContext *C, void *owner, ID *id, int sizex, int sizey)
866 {
867         wmJob *steve;
868         ShaderPreview *sp;
869
870         /* XXX ugly global still, but we can't do preview while rendering */
871         if(G.rendering)
872                 return;
873
874         steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), owner);
875         sp= MEM_callocN(sizeof(ShaderPreview), "shader preview");
876
877         /* customdata for preview thread */
878         sp->scene= CTX_data_scene(C);
879         sp->owner= owner;
880         sp->sizex= sizex;
881         sp->sizey= sizey;
882         sp->pr_method= PR_DO_RENDER;
883         sp->id = id;
884         
885         /* setup job */
886         WM_jobs_customdata(steve, sp, shader_preview_free);
887         WM_jobs_timer(steve, 0.1, NC_MATERIAL, NC_MATERIAL);
888         WM_jobs_callbacks(steve, shader_preview_startjob, NULL, shader_preview_updatejob);
889         
890         WM_jobs_start(CTX_wm_manager(C), steve);
891         
892         /* signal to rerender icon in menus */
893         BKE_icon_changed(BKE_icon_getid(id));
894 }
895
896 /* rect should be allocated, sizex/sizy pixels, 32 bits */
897 void ED_preview_iconrender(Scene *scene, ID *id, int *rect, int sizex, int sizey)
898 {
899         ShaderPreview *sp= MEM_callocN(sizeof(ShaderPreview), "ShaderPreview");
900         short stop=0, do_update=0;
901         
902         /* customdata for preview thread */
903         sp->scene= scene;
904         sp->sizex= sizex;
905         sp->sizey= sizey;
906         sp->pr_method= PR_ICON_RENDER;
907         sp->pr_rect= rect;
908         sp->id = id;
909
910         shader_preview_startjob(sp, &stop, &do_update);
911         
912         MEM_freeN(sp);
913 }
914
915
916