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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTon Roosendaal <ton@blender.org>2006-01-24 01:05:47 +0300
committerTon Roosendaal <ton@blender.org>2006-01-24 01:05:47 +0300
commit042d612df219c8f6a29afa235537380f227b5684 (patch)
tree310a2c859b99c559115bbcda0aa70f2543bf962c /source/blender/src/previewrender.c
parent5668480c99001a617fd59a2383deb858195ffb26 (diff)
Giant commit!
A full detailed description of this will be done later... is several days of work. Here's a summary: Render: - Full cleanup of render code, removing *all* globals and bad level calls all over blender. Render module is now not called abusive anymore - API-fied calls to rendering - Full recode of internal render pipeline. Is now rendering tiles by default, prepared for much smarter 'bucket' render later. - Each thread now can render a full part - Renders were tested with 4 threads, goes fine, apart from some lookup tables in softshadow and AO still - Rendering is prepared to do multiple layers and passes - No single 32 bits trick in render code anymore, all 100% floats now. Writing images/movies - moved writing images to blender kernel (bye bye 'schrijfplaatje'!) - made a new Movie handle system, also in kernel. This will enable much easier use of movies in Blender PreviewRender: - Using new render API, previewrender (in buttons) now uses regular render code to generate images. - new datafile 'preview.blend.c' has the preview scenes in it - previews get rendered in exact displayed size (1 pixel = 1 pixel) 3D Preview render - new; press Pkey in 3d window, for a panel that continuously renders (pkey is for games, i know... but we dont do that in orange now!) - this render works nearly identical to buttons-preview render, so it stops rendering on any event (mouse, keyboard, etc) - on moving/scaling the panel, the render code doesn't recreate all geometry - same for shifting/panning view - all other operations (now) regenerate the full render database still. - this is WIP... but big fun, especially for simple scenes! Compositor - Using same node system as now in use for shaders, you can composit images - works pretty straightforward... needs much more options/tools and integration with rendering still - is not threaded yet, nor is so smart to only recalculate changes... will be done soon! - the "Render Result" node will get all layers/passes as output sockets - The "Output" node renders to a builtin image, which you can view in the Image window. (yes, output nodes to render-result, and to files, is on the list!) The Bad News - "Unified Render" is removed. It might come back in some stage, but this system should be built from scratch. I can't really understand this code... I expect it is not much needed, especially with advanced layer/passes control - Panorama render, Field render, Motion blur, is not coded yet... (I had to recode every single feature in render, so...!) - Lens Flare is also not back... needs total revision, might become composit effect though (using zbuffer for visibility) - Part render is gone! (well, thats obvious, its default now). - The render window is only restored with limited functionality... I am going to check first the option to render to a Image window, so Blender can become a true single-window application. :) For example, the 'Spare render buffer' (jkey) doesnt work. - Render with border, now default creates a smaller image - No zbuffers are written yet... on the todo! - Scons files and MSVC will need work to get compiling again OK... thats what I can quickly recall. Now go compiling!
Diffstat (limited to 'source/blender/src/previewrender.c')
-rw-r--r--source/blender/src/previewrender.c1658
1 files changed, 435 insertions, 1223 deletions
diff --git a/source/blender/src/previewrender.c b/source/blender/src/previewrender.c
index a632eb6661e..043128673aa 100644
--- a/source/blender/src/previewrender.c
+++ b/source/blender/src/previewrender.c
@@ -46,14 +46,12 @@
#include <io.h>
#endif
#include "MEM_guardedalloc.h"
+
#include "BLI_arithb.h"
+#include "BLI_blenlib.h"
#include "MTC_matrixops.h"
-#include "render.h"
-#include "mydevice.h"
-
-#include "DNA_group_types.h"
#include "DNA_texture_types.h"
#include "DNA_world_types.h"
#include "DNA_camera_types.h"
@@ -63,12 +61,15 @@
#include "DNA_object_types.h"
#include "DNA_lamp_types.h"
#include "DNA_space_types.h"
+#include "DNA_view3d_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_icons.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
#include "BKE_texture.h"
#include "BKE_material.h"
#include "BKE_node.h"
@@ -81,6 +82,7 @@
#include "BSE_headerbuttons.h"
#include "BSE_node.h"
+#include "BSE_view.h"
#include "BIF_gl.h"
#include "BIF_screen.h"
@@ -94,194 +96,30 @@
#include "PIL_time.h"
-#include "RE_renderconverter.h"
+#include "RE_pipeline.h"
+#include "BLO_readfile.h"
#include "blendef.h" /* CLAMP */
-#include "interface.h" /* ui_graphics_to_window() SOLVE! (ton) */
+#include "interface.h" /* ui_graphics_to_window(), SOLVE! (ton) */
+#include "mydevice.h"
+
#define PR_XMIN 10
#define PR_YMIN 5
#define PR_XMAX 200
#define PR_YMAX 195
-#define PR_FACY (PR_YMAX-PR_YMIN-4)/(PR_RECTY)
-
-static rctf prerect;
-static float pr_facx, pr_facy;
-
-
-/* implementation */
-
-static short intersect(float *v1, float *v2, float *v3, float *rtlabda, float *ray1, float *ray2)
-{
- float x0,x1,x2,t00,t01,t02,t10,t11,t12,t20,t21,t22;
- float m0,m1,m2,deeldet,det1,det2,det3;
- float rtu, rtv;
-
- t00= v3[0]-v1[0];
- t01= v3[1]-v1[1];
- t02= v3[2]-v1[2];
- t10= v3[0]-v2[0];
- t11= v3[1]-v2[1];
- t12= v3[2]-v2[2];
- t20= ray1[0]-ray2[0];
- t21= ray1[1]-ray2[1];
- t22= ray1[2]-ray2[2];
-
- x0= t11*t22-t12*t21;
- x1= t12*t20-t10*t22;
- x2= t10*t21-t11*t20;
-
- deeldet= t00*x0+t01*x1+t02*x2;
- if(deeldet!=0.0f) {
- m0= ray1[0]-v3[0];
- m1= ray1[1]-v3[1];
- m2= ray1[2]-v3[2];
- det1= m0*x0+m1*x1+m2*x2;
- rtu= det1/deeldet;
- if(rtu<=0.0f) {
- det2= t00*(m1*t22-m2*t21);
- det2+= t01*(m2*t20-m0*t22);
- det2+= t02*(m0*t21-m1*t20);
- rtv= det2/deeldet;
- if(rtv<=0.0f) {
- if(rtu+rtv>= -1.0f) {
-
- det3= m0*(t12*t01-t11*t02);
- det3+= m1*(t10*t02-t12*t00);
- det3+= m2*(t11*t00-t10*t01);
- *rtlabda= det3/deeldet;
-
- if(*rtlabda>=0.0f && *rtlabda<=1.0f) {
- return 1;
- }
- }
- }
- }
- }
- return 0;
-}
-
-static float rcubev[7][3]= {
- {-0.002055, 6.627364, -3.369742},
- {-6.031684, -3.750204, -1.992980},
- {-6.049086, 3.817431, 1.969788},
- { 6.031685, 3.833064, 1.992979},
- { 6.049086, -3.734571, -1.969787},
- { 0.002054, -6.544502, 3.369744},
- {-0.015348, 1.023131, 7.332510} };
-
-static int rcubi[3][4]= {
- {3, 6, 5, 4},
- {1, 5, 6, 2},
- {3, 0, 2, 6} };
-
-
-static int ray_previewrender(int x, int y, float *vec, float *vn, short pr_rectx, short pr_recty)
-{
- /* float scalef= 10.0/100.0; - not fixed any more because of different render sizes */
- float scalef= ( 64.0f / (float)pr_rectx ) * 0.25f;
- float ray1[3], ray2[3];
- float minlabda, labda;
- int totface= 3, hitface= -1;
- int a;
-
- ray1[0]= ray2[0]= x*scalef;
- ray1[1]= ray2[1]= y*scalef;
- ray1[2]= -10.0f;
- ray2[2]= 10.0f;
-
- minlabda= 1.0f;
- for(a=0; a<totface; a++) {
- if(intersect( rcubev[rcubi[a][0]], rcubev[rcubi[a][1]], rcubev[rcubi[a][2]], &labda, ray1, ray2)) {
- if( labda < minlabda) {
- minlabda= labda;
- hitface= a;
- }
- }
- if(intersect( rcubev[rcubi[a][0]], rcubev[rcubi[a][2]], rcubev[rcubi[a][3]], &labda, ray1, ray2)) {
- if( labda < minlabda) {
- minlabda= labda;
- hitface= a;
- }
- }
- }
-
- if(hitface > -1) {
-
- CalcNormFloat(rcubev[rcubi[hitface][2]], rcubev[rcubi[hitface][1]], rcubev[rcubi[hitface][0]], vn);
-
- vec[0]= (minlabda*(ray1[0]-ray2[0])+ray2[0])/4.1;
- vec[1]= (minlabda*(ray1[1]-ray2[1])+ray2[1])/4.1;
- vec[2]= (minlabda*(ray1[2]-ray2[2])+ray2[2])/4.1;
-
- return 1;
- }
- return 0;
-}
-
-static unsigned int previewback(int type, int x, int y)
-{
- unsigned int col;
- char* pcol;
-
- /* checkerboard, for later
- x+= PR_RECTX/2;
- y+= PR_RECTX/2;
- if( ((x/24) + (y/24)) & 1) return 0x40404040;
- else return 0xa0a0a0a0;
- */
-
- if(type & MA_DARK) {
- if(abs(x)>abs(y)) col= 0;
- else col= 0x40404040;
- }
- else {
- if(abs(x)>abs(y)) col= 0x40404040;
- else col= 0xa0a0a0a0;
- }
- pcol = (char*) &col;
- pcol[3] = 0; /* set alpha to zero - endianess!*/
-
- return col;
-}
-
-static float previewbackf(int type, int x, int y)
-{
- float col;
-
- if(type & MA_DARK) {
- if(abs(x)>abs(y)) col= 0.0f;
- else col= 0.25f;
- }
- else {
- if(abs(x)>abs(y)) col= 0.25f;
- else col= 0.625f;
- }
- return col;
-}
-void set_previewrect(int win, int xmin, int ymin, int xmax, int ymax, short pr_rectx, short pr_recty)
+void set_previewrect(RenderInfo *ri, int win)
{
- float pr_sizex, pr_sizey;
+ rctf viewplane;
- prerect.xmin= xmin;
- prerect.ymin= ymin;
- prerect.xmax= xmax;
- prerect.ymax= ymax;
+ BLI_init_rctf(&viewplane, PR_XMIN, PR_XMAX, PR_YMIN, PR_YMAX);
- ui_graphics_to_window(win, &prerect.xmin, &prerect.ymin);
- ui_graphics_to_window(win, &prerect.xmax, &prerect.ymax);
+ ui_graphics_to_window_rct(win, &viewplane, &ri->disprect);
- pr_sizex= (prerect.xmax-prerect.xmin);
- pr_sizey= (prerect.ymax-prerect.ymin);
-
- pr_facx= ( pr_sizex-1.0f)/pr_rectx;
- pr_facy= ( pr_sizey-1.0f)/pr_recty;
-
/* correction for gla draw */
- prerect.xmin-= curarea->winrct.xmin;
- prerect.ymin-= curarea->winrct.ymin;
+ BLI_translate_rcti(&ri->disprect, -curarea->winrct.xmin, -curarea->winrct.ymin);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
@@ -290,8 +128,8 @@ void set_previewrect(int win, int xmin, int ymin, int xmax, int ymax, short pr_r
glaDefine2DArea(&curarea->winrct);
- glPixelZoom(pr_facx, pr_facy);
-
+ ri->pr_rectx= (ri->disprect.xmax-ri->disprect.xmin);
+ ri->pr_recty= (ri->disprect.ymax-ri->disprect.ymin);
}
static void end_previewrect(void)
@@ -301,31 +139,14 @@ static void end_previewrect(void)
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
- glPixelZoom(1.0f, 1.0f);
-
// restore viewport / scissor which was set by glaDefine2DArea
glViewport(curarea->winrct.xmin, curarea->winrct.ymin, curarea->winx, curarea->winy);
glScissor(curarea->winrct.xmin, curarea->winrct.ymin, curarea->winx, curarea->winy);
}
-static void display_pr_scanline(unsigned int *rect, int recty, short pr_rectx)
-{
-
- /* we do steps of 4 scanlines. but draw 5, because of errors in some gfx cards (nvidia geforce, ati...) */
- if( (recty & 3)==3) {
-
- if(recty == 3) {
- glaDrawPixelsSafe(prerect.xmin, prerect.ymin, pr_rectx, 4, GL_RGBA, GL_UNSIGNED_BYTE, rect);
- }
- else {
- rect+= (recty-4)*pr_rectx;
- glaDrawPixelsSafe(prerect.xmin, prerect.ymin + (((float)recty-4.0)*pr_facy), pr_rectx, 5, GL_RGBA, GL_UNSIGNED_BYTE, rect);
- }
- }
-}
-
-static void draw_tex_crop(Tex *tex)
+/* unused now */
+void draw_tex_crop(Tex *tex)
{
rcti rct;
int ret= 0;
@@ -391,1085 +212,191 @@ void BIF_preview_changed(short id_code)
snode_tag_dirty(snode);
}
}
- }
-}
-
-static void previewdraw_render(struct RenderInfo* ri, ScrArea* area)
-{
- int y;
-
- if (!ri) {
- return;
- }
-
- for (y=0; y<ri->pr_recty; y++) {
- display_pr_scanline(ri->rect, y, ri->pr_rectx);
- }
-}
-
-
-static void sky_preview_pixel(float lens, int x, int y, char *rect, short pr_rectx, short pr_recty)
-{
- float view[3];
-
- if(R.wrld.skytype & WO_SKYPAPER) {
- view[0]= (2*x)/(float)pr_rectx;
- view[1]= (2*y)/(float)pr_recty;
- view[2]= 0.0f;
- }
- else {
- view[0]= x;
- view[1]= y;
- view[2]= -lens*pr_rectx/32.0;
- Normalise(view);
- }
- RE_sky_char(view, rect);
- rect[3] = 0xFF;
-}
-
- static void init_preview_world(World* wrld)
- {
- int a;
- char *cp;
-
- if(wrld) {
- R.wrld= *(wrld);
-
- cp= (char *)&R.wrld.fastcol;
-
- cp[0]= 255.0*R.wrld.horr;
- cp[1]= 255.0*R.wrld.horg;
- cp[2]= 255.0*R.wrld.horb;
- cp[3]= 1;
-
- VECCOPY(R.grvec, R.viewmat[2]);
- Normalise(R.grvec);
- Mat3CpyMat4(R.imat, R.viewinv);
-
- for(a=0; a<MAX_MTEX; a++)
- if(R.wrld.mtex[a] && R.wrld.mtex[a]->tex) R.wrld.skytype |= WO_SKYTEX;
-
- while(R.wrld.aosamp*R.wrld.aosamp < R.osa) R.wrld.aosamp++;
- }
- else {
- memset(&R.wrld, 0, sizeof(World));
- R.wrld.exp= 0.0;
- R.wrld.range= 1.0;
- }
-
- R.wrld.linfac= 1.0 + pow((2.0*R.wrld.exp + 0.5), -10);
- R.wrld.logfac= log( (R.wrld.linfac-1.0)/R.wrld.linfac )/R.wrld.range;
-}
-
- /* This function carefully copies over the struct members
- from the struct Lamp to a new struct LampRen.
- It only copies the struct members that are needed
- in the lamp_preview_pixel function.
- Replacement for the RE_add_render_lamp function in
- the preview, because this only works for the
- current selected lamp.
- */
-static LampRen* create_preview_render_lamp(Lamp* la)
-{
- LampRen *lar;
- int c;
-
- lar= (LampRen *)MEM_callocN(sizeof(LampRen),"lampren");
-
- MTC_Mat3One(lar->mat);
- MTC_Mat3One(lar->imat);
-
- lar->type= la->type;
- lar->mode= la->mode;
- lar->energy= la->energy;
- if(la->mode & LA_NEG) lar->energy= -lar->energy;
- lar->r= lar->energy*la->r;
- lar->g= lar->energy*la->g;
- lar->b= lar->energy*la->b;
- lar->k= la->k;
- lar->dist= la->dist;
- lar->ld1= la->att1;
- lar->ld2= la->att2;
-
- /* exceptions: */
- lar->spottexfac= 1.0;
- lar->spotsi= cos( M_PI/3.0 );
- lar->spotbl= (1.0-lar->spotsi)*la->spotblend;
-
- MTC_Mat3One(lar->imat);
-
- if(lar->type==LA_SPOT) {
- if(lar->mode & LA_ONLYSHADOW) {
- if((lar->mode & (LA_SHAD|LA_SHAD_RAY))==0) lar->mode -= LA_ONLYSHADOW;
- }
- }
- memcpy(lar->mtex, la->mtex, MAX_MTEX*sizeof(void *));
-
- for(c=0; c<MAX_MTEX; c++) {
- if(la->mtex[c] && la->mtex[c]->tex) {
- lar->mode |= LA_TEXTURE;
-
- if(R.flag & R_RENDERING) {
- if(R.osa) {
- if(la->mtex[c]->tex->type==TEX_IMAGE) lar->mode |= LA_OSATEX;
- }
- }
- }
- }
-
- return lar;
-}
-
-static void lamp_preview_pixel(ShadeInput *shi, LampRen *la, int x, int y, char *rect, short pr_rectx, short pr_recty)
-{
- float inpr, i, t, dist, distkw, vec[3], lacol[3];
- int col;
-
- shi->co[0]= (float)x/(pr_rectx/4);
- shi->co[1]= (float)y/(pr_rectx/4);
- shi->co[2]= 0;
-
- vec[0]= 0.02f*x;
- vec[1]= 0.02f*y;
- vec[2]= 0.005f*pr_rectx;
- VECCOPY(shi->view, vec);
- dist= Normalise(shi->view);
-
- lacol[0]= la->r;
- lacol[1]= la->g;
- lacol[2]= la->b;
-
- if(la->mode & LA_TEXTURE) do_lamp_tex(la, vec, shi, lacol);
-
- if(la->type==LA_SUN || la->type==LA_HEMI) {
- dist= 1.0f;
- }
- else {
-
- if(la->mode & LA_QUAD) {
-
- t= 1.0f;
- if(la->ld1>0.0f)
- t= la->dist/(la->dist+la->ld1*dist);
- if(la->ld2>0.0f) {
- distkw= la->dist*la->dist;
- t= t*distkw/(t*distkw+la->ld2*dist*dist);
+ else if(sa->spacetype==SPACE_VIEW3D) {
+ View3D *vd= sa->spacedata.first;
+ /* if is has a renderinfo, we consider that reason for signalling */
+ if (vd->ri) {
+ vd->ri->cury= 0;
+ addafterqueue(sa->win, RENDERPREVIEW, 1);
}
- dist= t;
- }
- else {
- dist= (la->dist/(la->dist+dist));
}
}
-
- /* yafray: preview shade as spot, sufficient */
- if ((la->type==LA_SPOT) || (la->type==LA_YF_PHOTON)) {
-
-
- if(la->mode & LA_SQUARE) {
- /* slightly smaller... */
- inpr= 1.7*cos(MAX2(fabs(shi->view[0]/shi->view[2]) , fabs(shi->view[1]/shi->view[2]) ));
- }
- else {
- inpr= shi->view[2];
- }
-
- t= la->spotsi;
- if(inpr<t) dist= 0.0f;
- else {
- t= inpr-t;
- if(t<la->spotbl && la->spotbl!=0.0f) {
- /* soft area */
- i= t/la->spotbl;
- t= i*i;
- i= t*i;
- inpr*=(3.0*t-2.0*i);
- }
- }
- dist*=inpr;
- }
- else if ELEM(la->type, LA_LOCAL, LA_AREA) dist*= shi->view[2];
-
- col= 255.0*dist*lacol[0];
- if(col<=0) rect[0]= 0; else if(col>=255) rect[0]= 255; else rect[0]= col;
-
- col= 255.0*dist*lacol[1];
- if(col<=0) rect[1]= 0; else if(col>=255) rect[1]= 255; else rect[1]= col;
-
- col= 255.0*dist*lacol[2];
- if(col<=0) rect[2]= 0; else if(col>=255) rect[2]= 255; else rect[2]= col;
-
- rect[3] = 0xFF;
}
-static void init_previewhalo(HaloRen *har, Material *mat, short pr_rectx, short pr_recty)
-{
-
- har->type= 0;
- if(mat->mode & MA_HALO_XALPHA) har->type |= HA_XALPHA;
- har->mat= mat;
- har->hard= mat->har;
- har->rad= pr_rectx/2.0;
- har->radsq= pr_rectx*pr_rectx/4.0;
- har->alfa= mat->alpha;
- har->add= 255.0*mat->add;
- har->r= mat->r;
- har->g= mat->g;
- har->b= mat->b;
- har->xs= pr_rectx/2.0;
- har->ys= pr_rectx/2.0;
- har->zs= har->zd= 0;
- har->seed= (mat->seed1 % 256);
-
- if( (mat->mode & MA_HALOTEX) && mat->mtex[0] ) har->tex= 1; else har->tex=0;
+/* *************************** Preview for buttons *********************** */
- if(mat->mode & MA_STAR) har->starpoints= mat->starc; else har->starpoints= 0;
- if(mat->mode & MA_HALO_LINES) har->linec= mat->linec; else har->linec= 0;
- if(mat->mode & MA_HALO_RINGS) har->ringc= mat->ringc; else har->ringc= 0;
- if(mat->mode & MA_HALO_FLARE) har->flarec= mat->flarec; else har->flarec= 0;
-
- if(har->flarec) {
- har->xs-= pr_rectx/3;
- har->ys+= pr_rectx/3;
-
- har->rad*= 0.3;
- har->radsq= har->rad*har->rad;
-
- har->pixels= har->rad*har->rad*har->rad;
- }
-}
+static Main *pr_main= NULL;
-static void halo_preview_pixel(HaloRen *har, int startx, int endx, int y, char *rect, short pr_rectx)
+void BIF_preview_init_dbase(void)
{
- float dist, xn, yn, xsq, ysq, colf[4];
- int x;
- char front[4];
+ BlendReadError bre;
+ BlendFileData *bfd;
+ extern int datatoc_preview_blend_size;
+ extern char datatoc_preview_blend[];
- if(har->flarec) yn= y-pr_rectx/3;
- else yn= y;
- ysq= yn*yn;
-
- for(x=startx; x<endx; x++) {
-
- if(har->flarec) xn= x+pr_rectx/3;
- else xn= x;
+ G.fileflags |= G_FILE_NO_UI;
+ bfd= BLO_read_from_memory(datatoc_preview_blend, datatoc_preview_blend_size, &bre);
+ if (bfd) {
+ pr_main= bfd->main;
- xsq= xn*xn;
- dist= xsq+ysq;
-
- if(dist<har->radsq) {
- RE_shadehalo(har, front, colf, 0, dist, xn, yn, har->flarec);
- RE_addalphaAddfac(rect, front, har->add);
- rect[3] = 0xFF; /* makes icon display all pixels */
- }
- rect+= 4;
+ MEM_freeN(bfd);
}
+ G.fileflags &= ~G_FILE_NO_UI;
}
-static void previewflare(RenderInfo *ri, HaloRen *har, short pr_rectx, short pr_recty, int pr_method)
+void BIF_preview_free_dbase(void)
{
- float ycor;
- unsigned int *rectot;
- int afmx, afmy, rectx, recty, y;
-
- /* check for "Preview" block already in calling function BIF_previewrender! - elubie */
-
- /* temps */
- ycor= R.ycor;
- rectx= R.rectx;
- recty= R.recty;
- afmx= R.afmx;
- afmy= R.afmy;
- rectot= R.rectot;
-
- R.r.postmul= R.r.postgamma= R.r.postsat= 1.0f;
- R.r.posthue= R.r.postadd= 0.0f;
- R.ycor= 1.0f;
- R.rectx= pr_rectx;
- R.recty= pr_recty;
- R.afmx= pr_rectx/2;
- R.afmy= pr_recty/2;
- R.rectot= ri->rect;
-
- waitcursor(1);
- RE_renderflare(har);
- waitcursor(0);
- // not sure why, either waitcursor or renderflare screws up (disabled then)
- //areawinset(curarea->win);
-
- /* draw can just be called this way, all settings are OK */
- if (pr_method==PR_DRAW_RENDER) {
- for (y=0; y<pr_recty; y++) {
- display_pr_scanline(ri->rect, y, pr_rectx);
- }
- }
-
- /* temps */
- R.ycor= ycor;
- R.rectx= rectx;
- R.recty= recty;
- R.afmx= afmx;
- R.afmy= afmy;
- R.rectot= rectot;
+ if(pr_main)
+ free_main(pr_main);
}
-static void texture_preview_pixel(Tex *tex, int x, int y, char *rect, short pr_rectx, short pr_recty)
+static Scene *preview_prepare_scene(RenderInfo *ri, ID *id, int pr_method)
{
- float i, v1, xsq, ysq, texvec[3];
- float tin=1.0f, tr, tg, tb, ta;
- int rgbnor, tracol, skip=0;
+ Scene *sce;
+ Base *base;
- if(tex->type==TEX_IMAGE) {
- v1= 1.0f/pr_rectx;
-
- texvec[0]= 0.5+v1*x;
- texvec[1]= 0.5+v1*y;
-
- /* no coordinate mapping, exception: repeat */
- if(tex->extend==TEX_REPEAT) {
- if(tex->xrepeat>1) {
- texvec[0] *= tex->xrepeat;
- if(texvec[0]>1.0f) texvec[0] -= (int)(texvec[0]);
- }
- if(tex->yrepeat>1) {
- texvec[1] *= tex->yrepeat;
- if(texvec[1]>1.0f) texvec[1] -= (int)(texvec[1]);
- }
- }
- else if(tex->extend==TEX_CHECKER) {
- texvec[0]= 0.5+1.6*v1*x;
- texvec[1]= 0.5+1.6*v1*y;
- }
- }
- else if(tex->type==TEX_ENVMAP) {
- if(tex->env) {
- ysq= y*y;
- xsq= x*x;
- if(xsq+ysq < (pr_rectx/2)*(pr_recty/2)) {
- texvec[2]= sqrt( (float)((pr_rectx/2)*(pr_recty/2)-xsq-ysq) );
- texvec[0]= -x;
- texvec[1]= -y;
- Normalise(texvec);
-
- i= 2.0*(texvec[2]);
- texvec[0]= (i*texvec[0]);
- texvec[1]= (i*texvec[1]);
- texvec[2]= (-1.0f+i*texvec[2]);
-
+ if(pr_main==NULL) return NULL;
+
+ sce= pr_main->scene.first;
+ if(sce) {
+ if(GS(id->name)==ID_MA) {
+ Material *mat= (Material *)id;
+
+ if(pr_method==PR_ICON_RENDER) {
+ sce->lay= 1<<MA_SPHERE_A;
}
else {
- skip= 1;
- tr= tg= tb= ta= 0.0f;
+ sce->lay= 1<<mat->pr_type;
+ if(mat->nodetree)
+ ntreeInitPreview(mat->nodetree, ri->pr_rectx, ri->pr_recty);
}
- }
- else {
- skip= 1;
- tr= tg= tb= ta= 0.0f;
- }
- }
- else {
- v1= 2.0/pr_rectx;
-
- texvec[0]= v1*x;
- texvec[1]= v1*y;
- texvec[2]= 0.0f;
- }
-
- if(skip==0) rgbnor= multitex_ext(tex, texvec, &tin, &tr, &tg, &tb, &ta);
- else rgbnor= 1;
-
- if(rgbnor & 1) {
-
- v1= 255.0*tr;
- rect[0]= CLAMPIS(v1, 0, 255);
- v1= 255.0*tg;
- rect[1]= CLAMPIS(v1, 0, 255);
- v1= 255.0*tb;
- rect[2]= CLAMPIS(v1, 0, 255);
-
- if(ta!=1.0f) {
- tracol= 64+100*(abs(x)>abs(y));
- tracol= (1.0f-ta)*tracol;
- rect[0]= tracol+ (rect[0]*ta) ;
- rect[1]= tracol+ (rect[1]*ta) ;
- rect[2]= tracol+ (rect[2]*ta) ;
-
+ for(base= sce->base.first; base; base= base->next) {
+ if(base->object->id.name[2]=='p') {
+ if(ELEM4(base->object->type, OB_MESH, OB_CURVE, OB_SURF, OB_MBALL))
+ assign_material(base->object, mat, base->object->actcol);
+ }
+ }
}
-
- rect[3] = 0xFF;
- }
- else {
- rect[0]= 255.0*tin;
- rect[1]= 255.0*tin;
- rect[2]= 255.0*tin;
- rect[3] = 0xFF;
+ return sce;
}
-}
-
-static float pr1_lamp[3]= {2.3, -2.4, -4.6}; /* note; is not used! */
-static float pr2_lamp[3]= {-8.8, -5.6, -1.5};
-static float pr1_col[3]= {0.8, 0.8, 0.8};
-static float pr2_col[3]= {0.5, 0.6, 0.7};
-
-static void refraction_prv(int *x, int *y, float *n, float index)
-{
- float dot, fac, view[3], len;
-
- index= 1.0f/index;
-
- view[0]= index*(float)*x;
- view[1]= ((float)*y)/index;
- view[2]= 20.0f;
- len= Normalise(view);
- dot= view[0]*n[0] + view[1]*n[1] + view[2]*n[2];
-
- if(dot>0.0f) {
- fac= 1.0f - (1.0f - dot*dot)*index*index;
- if(fac<= 0.0f) return;
- fac= -dot*index + sqrt(fac);
- }
- else {
- index = 1.0f/index;
- fac= 1.0f - (1.0f - dot*dot)*index*index;
- if(fac<= 0.0f) return;
- fac= -dot*index - sqrt(fac);
- }
-
- *x= (int)(len*(index*view[0] + fac*n[0]));
- *y= (int)(len*(index*view[1] + fac*n[1]));
+ return NULL;
}
-static void shade_lamp_loop_preview(ShadeInput *shi, ShadeResult *shr)
+/* prevent pointer from being 'hanging' in preview dbase */
+static void preview_exit_scene(RenderInfo *ri, ID *id)
{
- extern float fresnel_fac(float *view, float *vn, float ior, float fac);
- Material *mat= shi->mat;
- float inp, is, inprspec=0;
- float lv[3], *la, *vn, vnor[3];
- int a;
-
- if((mat->mode & MA_RAYMIRROR)==0) shi->ray_mirror= 0.0f;
- memset(shr, 0, sizeof(ShadeResult));
-
- do_material_tex(shi);
-
- shr->alpha= shi->alpha;
-
- if(mat->mode & (MA_ZTRA|MA_RAYTRANSP))
- if(mat->fresnel_tra!=0.0f)
- shr->alpha*= fresnel_fac(shi->view, shi->vn, mat->fresnel_tra_i, mat->fresnel_tra);
-
- if(mat->mode & MA_SHLESS) {
- shr->diff[0]= shi->r;
- shr->diff[1]= shi->g;
- shr->diff[2]= shi->b;
-
- }
- else {
-
- if(mat->texco & TEXCO_REFL) {
- inp= -2.0*(shi->vn[0]*shi->view[0]+shi->vn[1]*shi->view[1]+shi->vn[2]*shi->view[2]);
- shi->ref[0]= (shi->view[0]+inp*shi->vn[0]);
- shi->ref[1]= (shi->view[1]+inp*shi->vn[1]);
- shi->ref[2]= (shi->view[2]+inp*shi->vn[2]);
- /* normals in render are pointing different... rhm */
-// if(shi->pr_type==MA_SPHERE)
-// shi->ref[1]= -shi->ref[1];
- }
-
- for(a=0; a<2; a++) {
-
- if((mat->pr_lamp & (1<<a))==0) continue;
-
- if(a==0) la= pr1_lamp;
- else la= pr2_lamp;
-
- lv[0]= shi->co[0]-la[0];
- lv[1]= shi->co[1]-la[1];
- lv[2]= shi->co[2]-la[2];
- Normalise(lv);
-
- if(shi->spec>0.0f) {
- /* specular shaders */
- float specfac;
-
- if(mat->mode & MA_TANGENT_V) vn= shi->tang;
- else vn= shi->vn;
-
- if(mat->spec_shader==MA_SPEC_PHONG)
- specfac= Phong_Spec(vn, lv, shi->view, shi->har, mat->mode & MA_TANGENT_V);
- else if(mat->spec_shader==MA_SPEC_COOKTORR)
- specfac= CookTorr_Spec(vn, lv, shi->view, shi->har, mat->mode & MA_TANGENT_V);
- else if(mat->spec_shader==MA_SPEC_BLINN)
- specfac= Blinn_Spec(vn, lv, shi->view, mat->refrac, (float)shi->har, mat->mode & MA_TANGENT_V);
- else if(mat->spec_shader==MA_SPEC_WARDISO)
- specfac= WardIso_Spec(vn, lv, shi->view, mat->rms, mat->mode & MA_TANGENT_V);
- else
- specfac= Toon_Spec(vn, lv, shi->view, mat->param[2], mat->param[3], mat->mode & MA_TANGENT_V);
-
- inprspec= specfac*shi->spec;
-
- if(mat->mode & MA_RAMP_SPEC) {
- float spec[3];
- do_specular_ramp(shi, specfac, inprspec, spec);
- shr->spec[0]+= inprspec*spec[0];
- shr->spec[1]+= inprspec*spec[1];
- shr->spec[2]+= inprspec*spec[2];
+ Scene *sce;
+ Base *base;
+
+ if(pr_main==NULL) return;
+
+ sce= pr_main->scene.first;
+ if(sce) {
+ if(GS(id->name)==ID_MA) {
+ for(base= sce->base.first; base; base= base->next) {
+ if(base->object->id.name[2]=='p') {
+ if(ELEM4(base->object->type, OB_MESH, OB_CURVE, OB_SURF, OB_MBALL))
+ assign_material(base->object, NULL, base->object->actcol);
}
- else {
- shr->spec[0]+= inprspec*shi->specr;
- shr->spec[1]+= inprspec*shi->specg;
- shr->spec[2]+= inprspec*shi->specb;
- }
- }
-
- if(mat->mode & MA_TANGENT_V) {
- float cross[3];
- Crossf(cross, lv, shi->tang);
- Crossf(vnor, cross, shi->tang);
- vnor[0]= -vnor[0];vnor[1]= -vnor[1];vnor[2]= -vnor[2];
- vn= vnor;
}
- else vn= shi->vn;
-
- is= vn[0]*lv[0]+vn[1]*lv[1]+vn[2]*lv[2];
- if(is<0.0f) is= 0.0f;
-
- /* diffuse shaders */
- if(mat->diff_shader==MA_DIFF_ORENNAYAR) is= OrenNayar_Diff(vn, lv, shi->view, mat->roughness);
- else if(mat->diff_shader==MA_DIFF_TOON) is= Toon_Diff(vn, lv, shi->view, mat->param[0], mat->param[1]);
- else if(mat->diff_shader==MA_DIFF_MINNAERT) is= Minnaert_Diff(is, vn, shi->view, mat->darkness);
- else if(mat->diff_shader==MA_DIFF_FRESNEL) is= Fresnel_Diff(vn, lv, shi->view, mat->param[0], mat->param[1]);
- // else Lambert
-
- inp= (shi->refl*is + shi->emit);
-
- if(a==0) la= pr1_col;
- else la= pr2_col;
-
- add_to_diffuse(shr->diff, shi, is, inp*la[0], inp*la[1], inp*la[2]);
- }
- /* end lamp loop */
-
- /* drawing checkerboard and sky */
- if(mat->mode & MA_RAYMIRROR) {
- float col, div, y, z;
- int fac;
-
- /* rotate a bit in x */
- y= shi->ref[1]; z= shi->ref[2];
- shi->ref[1]= 0.98*y - 0.17*z;
- shi->ref[2]= 0.17*y + 0.98*z;
-
- /* scale */
- div= (0.85f*shi->ref[1]);
-
- shi->refcol[0]= shi->ray_mirror*fresnel_fac(shi->view, shi->vn, mat->fresnel_mir_i, mat->fresnel_mir);
- /* not real 'alpha', but mirror overriding transparency */
- if(mat->mode & MA_RAYTRANSP) {
- float fac= sqrt(shi->refcol[0]);
- shr->alpha= shr->alpha*(1.0f-fac) + fac;
- }
- else shr->alpha= shr->alpha*(1.0f-shi->refcol[0]) + shi->refcol[0];
-
- if(div<0.0f) {
- /* minus 0.5 prevents too many small tiles in distance */
- fac= (int)(shi->ref[0]/(div-0.1f) ) + (int)(shi->ref[2]/(div-0.1f) );
- if(fac & 1) col= 0.8f;
- else col= 0.3f;
-
- shi->refcol[1]= shi->refcol[0]*col;
- shi->refcol[2]= shi->refcol[1];
- shi->refcol[3]= shi->refcol[2];
- }
- else {
- shi->refcol[1]= 0.0f;
- shi->refcol[2]= shi->refcol[0]*0.3f*div;
- shi->refcol[3]= shi->refcol[0]*0.8f*div;
- }
- }
- else
- shi->refcol[0]= 0.0f;
-
- shr->diff[0]+= shi->ambr;
- shr->diff[1]+= shi->ambg;
- shr->diff[2]+= shi->ambb;
-
- if(mat->mode & MA_RAMP_COL) ramp_diffuse_result(shr->diff, shi);
- if(mat->mode & MA_RAMP_SPEC) ramp_spec_result(shr->spec, shr->spec+1, shr->spec+2, shi);
-
- /* refcol */
- if(shi->refcol[0]!=0.0f) {
- shr->diff[0]= shi->mirr*shi->refcol[1] + (1.0f - shi->mirr*shi->refcol[0])*shr->diff[0];
- shr->diff[1]= shi->mirg*shi->refcol[2] + (1.0f - shi->mirg*shi->refcol[0])*shr->diff[1];
- shr->diff[2]= shi->mirb*shi->refcol[3] + (1.0f - shi->mirb*shi->refcol[0])*shr->diff[2];
- }
-
- /* ztra shade */
- if(shi->spectra!=0.0f) {
- inp = MAX3(shr->spec[0], shr->spec[1], shr->spec[2]);
- inp *= shi->spectra;
- if(inp>1.0f) inp= 1.0f;
- shr->alpha= (1.0f-inp)*shr->alpha+inp;
}
}
}
-static void shade_preview_pixel(ShadeInput *shi, float *vec, int x, int y, char *rect, short pr_rectx, short pr_recty)
+static void previewrender_progress(RenderResult *rr, rcti *unused)
{
- Material *mat;
- ShadeResult shr;
- float v1;
- float eul[3], tmat[3][3], imat[3][3], col[4];
-
- mat= shi->mat;
-
- v1= 0.5/pr_rectx;
- shi->view[0]= v1*x;
- shi->view[1]= v1*y;
- shi->view[2]= -1.0f;
- Normalise(shi->view);
+ RenderLayer *rl;
+ RenderInfo *ri= G.buts->ri;
+ float ofsx, ofsy;
- shi->xs= x + pr_rectx/2;
- shi->ys= y + pr_recty/2;
+ rl= rr->layers.first;
- shi->refcol[0]= shi->refcol[1]= shi->refcol[2]= shi->refcol[3]= 0.0f;
- VECCOPY(shi->co, vec);
+ ofsx= ri->disprect.xmin + rr->tilerect.xmin;
+ ofsy= ri->disprect.ymin + rr->tilerect.ymin;
- /* texture handling */
- if(mat->texco) {
-
- VECCOPY(shi->lo, vec);
-
- if(mat->pr_type==MA_CUBE) {
-
- eul[0]= (297)*M_PI/180.0;
- eul[1]= 0.0;
- eul[2]= (45)*M_PI/180.0;
- EulToMat3(eul, tmat);
-
- MTC_Mat3MulVecfl(tmat, shi->lo);
- MTC_Mat3MulVecfl(tmat, shi->vn);
- /* hack for cubemap, why!!! */
- SWAP(float, shi->vn[0], shi->vn[1]);
- }
- /* textures otherwise upside down */
- if(mat->pr_type==MA_CUBE || mat->pr_type==MA_SPHERE)
- shi->lo[2]= -shi->lo[2];
-
- if(mat->texco & TEXCO_GLOB) {
- VECCOPY(shi->gl, shi->lo);
- }
- if(mat->texco & TEXCO_WINDOW) {
- VECCOPY(shi->winco, shi->lo);
- }
- if(mat->texco & TEXCO_STICKY) {
- VECCOPY(shi->sticky, shi->lo);
- }
- if(mat->texco & TEXCO_UV) {
- VECCOPY(shi->uv, shi->lo);
- }
- if(mat->texco & TEXCO_STRAND) {
- shi->strand= shi->lo[0];
- }
- if(mat->texco & TEXCO_OBJECT) {
- /* nothing */
- }
- if(mat->texco & (TEXCO_NORM)) {
- //shi->orn[0]= shi->vn[0];
- //shi->orn[1]= shi->vn[1];
- //shi->orn[2]= shi->vn[2];
- }
-
- /* Clear displase vec for preview */
- shi->displace[0]= shi->displace[1]= shi->displace[2]= 0.0;
-
- if(mat->pr_type==MA_CUBE) {
- /* rotate normal back for normals texture */
- SWAP(float, shi->vn[0], shi->vn[1]);
- MTC_Mat3Inv(imat, tmat);
- MTC_Mat3MulVecfl(imat, shi->vn);
- }
-
- }
-
- if(mat->mapto & MAP_DISPLACE) { /* Quick hack of fake displacement preview */
-// shi->vn[0]-=2.0*shi->displace[2];
-// shi->vn[1]-=2.0*shi->displace[0];
-// shi->vn[2]+=2.0*shi->displace[1];
-// Normalise(shi->vn);
- }
-
- VECCOPY(shi->vno, shi->vn);
- if(mat->nodetree && mat->use_nodes) {
- ntreeShaderExecTree(mat->nodetree, shi, &shr);
- }
- else {
- /* copy all relevant material vars, note, keep this synced with render_types.h */
- memcpy(&shi->r, &mat->r, 23*sizeof(float));
- shi->har= mat->har;
-
- shade_lamp_loop_preview(shi, &shr);
- }
-
- shi->mat= mat; /* restore, shade input is re-used! */
-
- /* after shading and composit layers */
- if(shr.spec[0]<0.0f) shr.spec[0]= 0.0f;
- if(shr.spec[1]<0.0f) shr.spec[1]= 0.0f;
- if(shr.spec[2]<0.0f) shr.spec[2]= 0.0f;
-
- if(shr.diff[0]<0.0f) shr.diff[0]= 0.0f;
- if(shr.diff[1]<0.0f) shr.diff[1]= 0.0f;
- if(shr.diff[2]<0.0f) shr.diff[2]= 0.0f;
-
- VECADD(col, shr.diff, shr.spec);
- col[3]= shr.alpha;
-
- /* handle backdrop now */
-
- if(col[3]!=1.0f) {
- float back, backm;
-
- /* distorts x and y */
- if(mat->mode & MA_RAYTRANSP) {
- refraction_prv(&x, &y, shi->vn, shi->ang);
- }
-
- back= previewbackf(mat->pr_back, x, y);
- backm= (1.0f-shr.alpha)*back;
-
- if((mat->mode & MA_RAYTRANSP) && mat->filter!=0.0) {
- float fr= 1.0f+ mat->filter*(shr.diff[0]-1.0f);
- col[0]= fr*backm+ (col[3]*col[0]);
- fr= 1.0f+ mat->filter*(shr.diff[1]-1.0f);
- col[1]= fr*backm+ (col[3]*col[1]);
- fr= 1.0f+ mat->filter*(shr.diff[2]-1.0f);
- col[2]= fr*backm+ (col[3]*col[2]);
- }
- else {
- col[0]= backm + (col[3]*col[0]);
- col[1]= backm + (col[3]*col[1]);
- col[2]= backm + (col[3]*col[2]);
- }
- }
-
- if(col[0]<=0.0f) rect[0]= 0; else if(col[0]>=1.0f) rect[0]= 255; else rect[0]= (char)(255.0f*col[0]);
- if(col[1]<=0.0f) rect[1]= 0; else if(col[1]>=1.0f) rect[1]= 255; else rect[1]= (char)(255.0f*col[1]);
- if(col[2]<=0.0f) rect[2]= 0; else if(col[2]>=1.0f) rect[2]= 255; else rect[2]= (char)(255.0f*col[2]);
- if(col[3]<=0.0f) rect[3]= 0; else if(col[3]>=1.0f) rect[3]= 255; else rect[3]= (char)(255.0f*col[3]);
+ glDrawBuffer(GL_FRONT);
+ glaDrawPixelsSafe(ofsx, ofsy, rr->rectx, rr->recty, rr->rectx, GL_RGBA, GL_FLOAT, rl->rectf);
+ glFlush();
+ glDrawBuffer(GL_BACK);
}
-static void preview_init_render_textures(MTex **mtex)
-{
- int x;
-
- for(x=0; x<MAX_MTEX; x++) {
- if(mtex[x]) {
- if(mtex[x]->tex) {
- init_render_texture(mtex[x]->tex);
-
- if(mtex[x]->tex->env && mtex[x]->tex->env->object)
- MTC_Mat4One(mtex[x]->tex->env->object->imat);
-
- }
- if(mtex[x]->object) MTC_Mat4One(mtex[x]->object->imat);
- if(mtex[x]->object) MTC_Mat4One(mtex[x]->object->imat);
- }
- }
-
-}
-/* main previewrender loop */
+/* called by interface_icons.c, or by BIF_previewrender_buts or by nodes... */
void BIF_previewrender(struct ID *id, struct RenderInfo *ri, struct ScrArea *area, int pr_method)
{
- static double lasttime= 0;
- Material *mat= NULL;
- Tex *tex= NULL;
- Lamp *la= NULL;
- World *wrld= NULL;
- LampRen *lar= NULL;
- Image *ima;
- HaloRen har;
- Object *ob;
- ShadeInput shi;
- float lens = 0.0, vec[3];
- int x, y, starty, startx, endy, endx, radsq, xsq, ysq, last = 0;
- unsigned int *rect;
-
- if(ri->cury>=ri->pr_rectx) return;
+ Render *re;
+ RenderStats *rstats;
+ Scene *sce;
+ char name [32];
- ob= ((G.scene->basact)? (G.scene->basact)->object: 0);
-
- switch(GS(id->name))
- {
- case ID_MA:
- mat = (Material*)id; break;
- case ID_TE:
- tex = (Tex*)id; break;
- case ID_LA:
- la = (Lamp*)id; break;
- case ID_WO:
- wrld = (World*)id; break;
- default:
- return;
- }
+ if(ri->cury>=ri->pr_recty) return;
- har.flarec= 0; /* below is a test for postrender flare */
-
- /* no event escape for icon render */
+ if(ri->rect==NULL) {
+ ri->rect= MEM_callocN(sizeof(int)*ri->pr_rectx*ri->pr_recty, "butsrect");
+ }
+
+ /* check for return with a new event */
if(pr_method!=PR_ICON_RENDER && qtest()) {
- addafterqueue(curarea->win, RENDERPREVIEW, 1);
+ if(area)
+ addafterqueue(area->win, RENDERPREVIEW, 1);
return;
}
-
- MTC_Mat4One(R.viewmat);
- MTC_Mat4One(R.viewinv);
- shi.osatex= 0;
+ /* get the stuff from the builtin preview dbase */
+ sce= preview_prepare_scene(ri, id, pr_method);
+ if(sce==NULL) return;
- if(mat) {
-
- /* rendervars */
- init_render_world();
- init_render_material(mat); /* does nodes too */
-
- /* also clears imats */
- preview_init_render_textures(mat->mtex);
-
- /* do the textures for nodes */
- if(mat->nodetree && mat->use_nodes) {
- bNode *node;
- for(node=mat->nodetree->nodes.first; node; node= node->next) {
- if(node->id && GS(node->id->name)==ID_MA) {
- Material *ma= (Material *)node->id;
- preview_init_render_textures(ma->mtex);
- }
- }
- /* signal to node editor to store previews or not */
- if(pr_method==PR_ICON_RENDER) {
- shi.do_preview= 0;
- }
- else {
- ntreeInitPreview(mat->nodetree, ri->pr_rectx, ri->pr_recty);
- shi.do_preview= 1;
- }
- }
- shi.vlr= NULL;
- shi.mat= mat;
- shi.pr_type= mat->pr_type;
-
- if(mat->mode & MA_HALO) init_previewhalo(&har, mat, ri->pr_rectx, ri->pr_recty);
-
- set_node_shader_lamp_loop(shade_lamp_loop_preview);
+ /* just create new render always now */
+ sprintf(name, "ButsPreview %d", area?area->win:0);
+ re= RE_NewRender(name);
+
+ /* handle cases */
+ if(pr_method==PR_DRAW_RENDER) {
+ RE_display_draw_cb(re, previewrender_progress);
+ RE_test_break_cb(re, qtest);
+ sce->r.scemode |= R_NODE_PREVIEW;
}
- else if(tex) {
-
- ima= tex->ima;
- if(ima) last= ima->lastframe;
- init_render_texture(tex);
- free_unused_animimages();
- if(tex->ima) {
- if(tex->ima!=ima) allqueue(REDRAWBUTSSHADING, 0);
- else if(last!=ima->lastframe) allqueue(REDRAWBUTSSHADING, 0);
- }
- if(tex->env && tex->env->object)
- MTC_Mat4Invert(tex->env->object->imat, tex->env->object->obmat);
+ else if(pr_method==PR_DO_RENDER) {
+ RE_test_break_cb(re, qtest);
+ sce->r.scemode |= R_NODE_PREVIEW;
}
- else if(la) {
-
- init_render_world();
- preview_init_render_textures(la->mtex);
-
- /* lar= ((GroupObject *)R.lights.first)->lampren;
- RE_add_render_lamp(ob, 0); */ /* 0=no shadbuf or tables */
-
- /* elubie: not nice, but ob contains current object, not usable if you
- need to render lamp that's not active object :( */
- lar = create_preview_render_lamp(la);
-
- /* exceptions: */
- lar->spottexfac= 1.0f;
- lar->spotsi= cos( M_PI/3.0f );
- lar->spotbl= (1.0f-lar->spotsi)*la->spotblend;
-
- MTC_Mat3One(lar->imat);
- }
- else if(wrld) {
-
- lens= 35.0;
- if(G.scene->camera) {
- lens= ( (Camera *)G.scene->camera->data)->lens;
-
- /* needed for init_render_world */
- MTC_Mat4CpyMat4(R.viewinv, G.scene->camera->obmat);
- MTC_Mat4Ortho(R.viewinv);
- MTC_Mat4Invert(R.viewmat, R.viewinv);
- }
- init_preview_world(wrld);
- preview_init_render_textures(wrld->mtex);
+ else { /* PR_ICON_RENDER */
+ sce->r.scemode &= ~R_NODE_PREVIEW;
}
- if(ri->rect==NULL) {
- ri->rect= MEM_callocN(sizeof(int)*ri->pr_rectx*ri->pr_recty, "butsrect");
- }
-
- starty= -ri->pr_recty/2;
- endy= starty+ri->pr_recty;
- starty+= ri->cury;
-
- startx= -ri->pr_rectx/2;
- endx= startx+ri->pr_rectx;
+ /* entire cycle for render engine */
+ RE_InitState(re, &sce->r, ri->pr_rectx, ri->pr_recty, NULL);
+ RE_SetCamera(re, sce->camera);
+ RE_Database_FromScene(re, sce, 1);
+ RE_TileProcessor(re); // actual render engine
+ RE_Database_Free(re);
- radsq= (ri->pr_rectx/2)*(ri->pr_recty/2);
-
- if(mat) {
- pr1_lamp[0]= -2.3; pr1_lamp[1]= 2.4; pr1_lamp[2]= 4.6;
- pr2_lamp[0]= 8.8; pr2_lamp[1]= 5.6; pr2_lamp[2]= 1.5;
-
+ /* handle results */
+ if(pr_method==PR_ICON_RENDER) {
+ RE_ResultGet32(re, ri->rect);
}
-
- if (pr_method==PR_DRAW_RENDER)
- glDrawBuffer(GL_FRONT);
-
- /* here it starts! */
- for(y=starty; y<endy; y++) {
-
- rect= ri->rect + ri->pr_rectx*ri->cury;
-
- if(mat) {
-
- if(mat->mode & MA_HALO) {
- for(x=startx; x<endx; x++, rect++) {
- rect[0]= previewback(mat->pr_back, x, y);
- }
-
- if(har.flarec) {
- if(y==endy-2) previewflare(ri, &har, ri->pr_rectx, ri->pr_recty, pr_method);
- }
- else {
- halo_preview_pixel(&har, startx, endx, y, (char *) (rect-ri->pr_rectx), ri->pr_rectx);
- }
- }
- else {
- ysq= y*y;
- for(x=startx; x<endx; x++, rect++) {
- xsq= x*x;
- if(mat->pr_type==MA_SPHERE) {
-
- if(xsq+ysq <= radsq) {
- shi.vn[0]= -x;
- shi.vn[1]= -y;
- shi.vn[2]= -sqrt( (float)(radsq-xsq-ysq) );
- Normalise(shi.vn);
-
- vec[0]= shi.vn[0];
- vec[1]= shi.vn[1];
- vec[2]= -shi.vn[2];
-
- if(mat->mode & MA_TANGENT_V) {
- float tmp[3];
- tmp[0]=tmp[2]= 0.0f;
- tmp[1]= 1.0f;
- Crossf(shi.tang, tmp, shi.vn);
- Normalise(shi.tang);
- }
-
- shade_preview_pixel(&shi, vec, x, y, (char *)rect, ri->pr_rectx, ri->pr_recty);
- }
- else {
- rect[0]= previewback(mat->pr_back, x, y);
-
- if(pr_method!=PR_ICON_RENDER && mat->nodetree && mat->use_nodes)
- ntreeClearPixelTree(mat->nodetree, x+ri->pr_rectx/2, y+ri->pr_recty/2);
- }
- }
- else if(mat->pr_type==MA_CUBE) {
- if( ray_previewrender(x, y, vec, shi.vn, ri->pr_rectx, ri->pr_recty) ) {
-
- shade_preview_pixel(&shi, vec, x, y, (char *)rect, ri->pr_rectx, ri->pr_recty);
- }
- else {
- rect[0]= previewback(mat->pr_back, x, y);
-
- if(pr_method!=PR_ICON_RENDER && mat->nodetree && mat->use_nodes)
- ntreeClearPixelTree(mat->nodetree, x+ri->pr_rectx/2, y+ri->pr_recty/2);
- }
- }
- else {
- vec[0]= x*(2.0f/ri->pr_rectx);
- vec[1]= y*(2.0f/ri->pr_recty);
- vec[2]= 0.0;
-
- shi.vn[0]= shi.vn[1]= 0.0f;
- shi.vn[2]= -1.0f;
-
- shade_preview_pixel(&shi, vec, x, y, (char *)rect, ri->pr_rectx, ri->pr_recty);
- }
- }
- }
- }
- else if(tex) {
- for(x=startx; x<endx; x++, rect++) {
- texture_preview_pixel(tex, x, y, (char *)rect, ri->pr_rectx, ri->pr_recty);
- }
- }
- else if(la) {
- for(x=startx; x<endx; x++, rect++) {
- lamp_preview_pixel(&shi, lar, x, y, (char *)rect, ri->pr_rectx, ri->pr_recty);
- }
- }
- else {
- for(x=startx; x<endx; x++, rect++) {
- sky_preview_pixel(lens, x, y, (char *)rect, ri->pr_rectx, ri->pr_recty);
- }
+ else {
+ rstats= RE_GetStats(re);
+ if(rstats->totpart==rstats->partsdone && rstats->partsdone) {
+ ri->cury= ri->pr_recty;
+ RE_ResultGet32(re, ri->rect);
+ if(GS(id->name)==ID_MA && ((Material *)id)->use_nodes)
+ allqueue(REDRAWNODE, 0);
}
-
- if (pr_method!=PR_ICON_RENDER) {
- if(y<endy-2) {
- if(qtest()) {
- addafterqueue(curarea->win, RENDERPREVIEW, 1);
- break;
- }
- }
- display_pr_scanline(ri->rect, ri->cury, ri->pr_rectx);
-
- /* flush opengl for cards with frontbuffer slowness */
- if(ri->cury==ri->pr_recty-1 || (PIL_check_seconds_timer() - lasttime > 0.05)) {
- lasttime= PIL_check_seconds_timer();
- glFlush();
+ else {
+ if(pr_method==PR_DRAW_RENDER && qtest()) {
+ addafterqueue(area->win, RENDERPREVIEW, 1);
}
}
- ri->cury++;
- }
-
- if (pr_method==PR_DRAW_RENDER) {
- if(ri->cury>=ri->pr_recty && tex)
- draw_tex_crop((Tex*)id);
-
- glDrawBuffer(GL_BACK);
- /* draw again for clean swapbufers */
- previewdraw_render(ri, area);
- }
-
- if(lar) {
- MEM_freeN(lar);
- /*
- MEM_freeN(R.lights.first);
- R.lights.first= R.lights.last= NULL;
- */
- }
-
- if(mat) {
- end_render_material(mat);
-
- if(mat->nodetree && mat->use_nodes)
- if(ri->cury>=ri->pr_recty)
- allqueue(REDRAWNODE, 0);
}
+ preview_exit_scene(ri, id);
+ RE_FreeRender(re);
}
+
+/* afterqueue call */
void BIF_previewrender_buts(SpaceButs *sbuts)
{
uiBlock *block;
@@ -1512,7 +439,7 @@ void BIF_previewrender_buts(SpaceButs *sbuts)
if (idshow) {
BKE_icon_changed(BKE_icon_getid(idshow));
uiPanelPush(block);
- set_previewrect(sbuts->area->win, PR_XMIN, PR_YMIN, PR_XMAX, PR_YMAX, sbuts->ri->pr_rectx, sbuts->ri->pr_recty); // uses UImat
+ set_previewrect(sbuts->ri, sbuts->area->win); // uses UImat
BIF_previewrender(idshow, sbuts->ri, sbuts->area, PR_DRAW_RENDER);
uiPanelPop(block);
end_previewrect();
@@ -1528,10 +455,11 @@ void BIF_previewrender_buts(SpaceButs *sbuts)
}
}
+
/* is panel callback, supposed to be called with correct panel offset matrix */
-void BIF_previewdraw(void)
+void BIF_previewdraw(ScrArea *sa, uiBlock *block)
{
- SpaceButs *sbuts= curarea->spacedata.first;
+ SpaceButs *sbuts= sa->spacedata.first;
short id_code= 0;
if(sbuts->lockpoin) {
@@ -1543,18 +471,302 @@ void BIF_previewdraw(void)
sbuts->ri= MEM_callocN(sizeof(RenderInfo), "butsrenderinfo");
sbuts->ri->cury = 0;
sbuts->ri->rect = NULL;
- sbuts->ri->pr_rectx = PREVIEW_RENDERSIZE;
- sbuts->ri->pr_recty = PREVIEW_RENDERSIZE;
}
if (sbuts->ri->rect==NULL) BIF_preview_changed(id_code);
else {
- set_previewrect(sbuts->area->win, PR_XMIN, PR_YMIN, PR_XMAX, PR_YMAX, sbuts->ri->pr_rectx, sbuts->ri->pr_recty);
- previewdraw_render(sbuts->ri, sbuts->area);
+ RenderInfo *ri= sbuts->ri;
+ int oldx= ri->pr_rectx, oldy= ri->pr_recty;
+
+ /* we now do scalable previews! */
+ set_previewrect(ri, sa->win);
+ if(oldx==ri->pr_rectx && oldy==ri->pr_recty)
+ glaDrawPixelsSafe(ri->disprect.xmin, ri->disprect.ymin, ri->pr_rectx, ri->pr_recty, ri->pr_rectx, GL_RGBA, GL_UNSIGNED_BYTE, ri->rect);
+ else {
+ MEM_freeN(ri->rect);
+ ri->rect= NULL;
+ sbuts->ri->cury= 0;
+ }
end_previewrect();
}
if(sbuts->ri->cury==0) BIF_preview_changed(id_code);
}
+/* *************************** Preview for 3d window *********************** */
+static void view3d_previewrender_stats(RenderStats *rs)
+{
+ printf("rendered %.3f\n", rs->lastframetime);
+}
+
+static void view3d_previewrender_progress(RenderResult *rr, rcti *unused)
+{
+ RenderLayer *rl;
+ int ofsx, ofsy;
+
+ rl= rr->layers.first;
+
+ /* this case is when we render envmaps... */
+ if(rr->rectx>G.vd->ri->pr_rectx || rr->recty>G.vd->ri->pr_recty)
+ return;
+
+ ofsx= G.vd->ri->disprect.xmin + rr->tilerect.xmin;
+ ofsy= G.vd->ri->disprect.ymin + rr->tilerect.ymin;
+
+ glDrawBuffer(GL_FRONT);
+ glaDefine2DArea(&curarea->winrct);
+ glaDrawPixelsSafe(ofsx, ofsy, rr->rectx, rr->recty, rr->rectx, GL_RGBA, GL_FLOAT, rl->rectf);
+ glFlush();
+ glDrawBuffer(GL_BACK);
+
+}
+
+void BIF_view3d_previewrender_signal(ScrArea *sa, short signal)
+{
+ View3D *v3d= sa->spacedata.first;
+
+ /* this can be called from other window... solve! */
+ if(sa->spacetype!=SPACE_VIEW3D)
+ v3d= G.vd;
+
+ if(v3d && v3d->ri) {
+ RenderInfo *ri= v3d->ri;
+ ri->status &= ~signal;
+ ri->cury= 0;
+ if(ri->re && (signal & PR_DBASE))
+ RE_Database_Free(ri->re);
+
+ addafterqueue(sa->win, RENDERPREVIEW, 1);
+ }
+}
+
+void BIF_view3d_previewrender_free(ScrArea *sa)
+{
+ View3D *v3d= sa->spacedata.first;
+
+ if(v3d->ri) {
+ RenderInfo *ri= v3d->ri;
+ if(ri->re) {
+// printf("free render\n");
+ RE_Database_Free(ri->re);
+ RE_FreeRender(ri->re);
+ ri->re= NULL;
+ }
+ ri->status= 0;
+ ri->cury= 0;
+ }
+}
+
+/* returns 1 if OK, do not call while in panel space! */
+static int view3d_previewrender_get_rects(ScrArea *sa, rctf *viewplane, RenderInfo *ri, float *clipsta, float *clipend, int *ortho)
+{
+ int rectx, recty;
+ uiBlock *block;
+
+ block= uiFindOpenPanelBlockName(&curarea->uiblocks, "Preview");
+ if(block==NULL) return 0;
+
+ /* calculate preview rect size */
+ BLI_init_rctf(viewplane, 15.0f, (block->maxx - block->minx)-15.0f, 15.0f, (block->maxy - block->miny)-15.0f);
+ uiPanelPush(block);
+ ui_graphics_to_window_rct(sa->win, viewplane, &ri->disprect);
+ uiPanelPop(block);
+
+ /* correction for gla draw */
+ BLI_translate_rcti(&ri->disprect, -sa->winrct.xmin, -sa->winrct.ymin);
+
+ *ortho= get_view3d_viewplane(sa->winx, sa->winy, viewplane, clipsta, clipend);
+
+ rectx= ri->disprect.xmax - ri->disprect.xmin;
+ recty= ri->disprect.ymax - ri->disprect.ymin;
+
+ if(rectx<4 || recty<4) return 0;
+
+ if(ri->rect && (rectx!=ri->pr_rectx || recty!=ri->pr_recty)) {
+ MEM_freeN(ri->rect);
+ ri->rect= NULL;
+ }
+ ri->pr_rectx= rectx;
+ ri->pr_recty= recty;
+
+ return 1;
+}
+
+/* called before a panel gets moved/scaled, makes sure we can see through */
+void BIF_view3d_previewrender_clear(ScrArea *sa)
+{
+ View3D *v3d= sa->spacedata.first;
+
+ if(v3d->ri) {
+ RenderInfo *ri= v3d->ri;
+ ri->cury= 0;
+ if(ri->rect)
+ MEM_freeN(ri->rect);
+ ri->rect= NULL;
+ }
+}
+
+/* afterqueue call */
+void BIF_view3d_previewrender(ScrArea *sa)
+{
+ View3D *v3d= sa->spacedata.first;
+ Render *re;
+ RenderInfo *ri; /* preview struct! */
+ RenderStats *rstats;
+ RenderData rdata;
+ rctf viewplane;
+ float clipsta, clipend;
+ int orth;
+
+ /* first get the render info right */
+ if (!v3d->ri)
+ ri= v3d->ri= MEM_callocN(sizeof(RenderInfo), "butsrenderinfo");
+ ri= v3d->ri;
+
+ if(0==view3d_previewrender_get_rects(sa, &viewplane, ri, &clipsta, &clipend, &orth))
+ return;
+
+ /* render is finished, so return */
+ if(ri->cury>=ri->pr_rectx) return;
+
+ /* or return with a new event */
+ if(qtest()) {
+ addafterqueue(curarea->win, RENDERPREVIEW, 1);
+ return;
+ }
+
+ /* ok, are we rendering all over? */
+ if(ri->re==NULL) {
+ char name[32];
+
+ ri->status= 0;
+
+ sprintf(name, "View3dPreview %d", sa->win);
+ re= ri->re= RE_NewRender(name);
+ RE_display_draw_cb(re, view3d_previewrender_progress);
+ RE_stats_draw_cb(re, view3d_previewrender_stats);
+ RE_test_break_cb(re, qtest);
+
+ /* no osa, blur, seq, for preview render */
+ rdata= G.scene->r;
+ rdata.mode &= ~(R_OSA|R_MBLUR|R_DOSEQ);
+
+ RE_InitState(re, &rdata, sa->winx, sa->winy, &ri->disprect);
+
+ if(orth)
+ RE_SetOrtho(re, &viewplane, clipsta, clipend);
+ else
+ RE_SetWindow(re, &viewplane, clipsta, clipend);
+
+ /* until here are no escapes */
+ ri->status |= PR_DISPRECT;
+ }
+
+ re= ri->re;
+
+ PIL_sleep_ms(100); /* wait 0.1 second if theres really no event... */
+ if(qtest()==0) {
+
+ /* check status */
+ if((ri->status & PR_DISPRECT)==0) {
+ RE_SetDispRect(ri->re, &ri->disprect);
+ if(orth)
+ RE_SetOrtho(ri->re, &viewplane, clipsta, clipend);
+ else
+ RE_SetWindow(ri->re, &viewplane, clipsta, clipend);
+ ri->status |= PR_DISPRECT;
+ }
+ if((ri->status & PR_DBASE)==0) {
+ unsigned int lay= G.scene->lay;
+
+ RE_SetView(re, G.vd->viewmat);
+
+ /* allow localview render for objects with lights in normal layers */
+ if(v3d->lay & 0xFF000000)
+ G.scene->lay |= v3d->lay;
+ else G.scene->lay= v3d->lay;
+
+ RE_Database_FromScene(re, G.scene, 0); // 0= dont use camera view
+ G.scene->lay= lay;
+
+ rstats= RE_GetStats(re);
+ if(rstats->convertdone)
+ ri->status |= PR_DBASE|PR_PROJECTED|PR_ROTATED;
+ }
+ if((ri->status & PR_PROJECTED)==0) {
+ if(ri->status & PR_DBASE) {
+ if(orth)
+ RE_SetOrtho(ri->re, &viewplane, clipsta, clipend);
+ else
+ RE_SetWindow(ri->re, &viewplane, clipsta, clipend);
+ RE_DataBase_ApplyWindow(re);
+ ri->status |= PR_PROJECTED;
+ }
+ }
+
+ /* OK, can we enter render code? */
+ if(ri->status==(PR_DISPRECT|PR_DBASE|PR_PROJECTED|PR_ROTATED)) {
+ RE_TileProcessor(ri->re);
+
+ if(ri->rect==NULL)
+ ri->rect= MEM_callocN(sizeof(int)*ri->pr_rectx*ri->pr_recty, "preview view3d rect");
+
+ RE_ResultGet32(ri->re, ri->rect);
+ }
+
+ rstats= RE_GetStats(ri->re);
+ if(rstats->totpart==rstats->partsdone && rstats->partsdone) {
+ ri->cury= 12000; /* arbitrary... */
+ addqueue(sa->win, REDRAW, 1);
+ }
+ else {
+ addafterqueue(curarea->win, RENDERPREVIEW, 1);
+ ri->cury= 0;
+ }
+ }
+ else {
+ addafterqueue(curarea->win, RENDERPREVIEW, 1);
+ ri->cury= 0;
+ }
+}
+
+/* in panel space! */
+static void view3d_previewdraw_rect(ScrArea *sa, uiBlock *block, RenderInfo *ri)
+{
+ rctf dispf;
+
+ if(ri->rect==NULL)
+ return;
+
+ BLI_init_rctf(&dispf, 15.0f, (block->maxx - block->minx)-15.0f, 15.0f, (block->maxy - block->miny)-15.0f);
+ ui_graphics_to_window_rct(sa->win, &dispf, &ri->disprect);
+
+ /* correction for gla draw */
+ BLI_translate_rcti(&ri->disprect, -curarea->winrct.xmin, -curarea->winrct.ymin);
+
+ /* when panel scale changed, free rect */
+ if(ri->disprect.xmax-ri->disprect.xmin != ri->pr_rectx ||
+ ri->disprect.ymax-ri->disprect.ymin != ri->pr_recty) {
+ MEM_freeN(ri->rect);
+ ri->rect= NULL;
+ }
+ else {
+ glaDefine2DArea(&sa->winrct);
+ glaDrawPixelsSafe(ri->disprect.xmin, ri->disprect.ymin, ri->pr_rectx, ri->pr_recty, ri->pr_rectx, GL_RGBA, GL_UNSIGNED_BYTE, ri->rect);
+ }
+}
+
+/* is panel callback, supposed to be called with correct panel offset matrix */
+void BIF_view3d_previewdraw(struct ScrArea *sa, struct uiBlock *block)
+{
+ View3D *v3d= sa->spacedata.first;
+
+ if (v3d->ri==NULL || v3d->ri->rect==NULL)
+ addafterqueue(sa->win, RENDERPREVIEW, 1);
+ else {
+ view3d_previewdraw_rect(sa, block, v3d->ri);
+ if(v3d->ri->cury==0)
+ addafterqueue(sa->win, RENDERPREVIEW, 1);
+ }
+}