ATMOS.C

Go to the documentation of this file.
00001 /* --
00002 OpenFX version 2.4 - Modelling, Animation and Rendering Package
00003 Copyright (C) 2000  - 2014 OpenFX Development Team
00004 -- */
00005 
00006 /* atmos.c  image post-processor                                        */
00007 /*                                                                      */
00008 
00009 #include <stdlib.h>
00010 #include <stdio.h>
00011 #include <float.h>
00012 #include <math.h>
00013 #include <windows.h>
00014 #include <commctrl.h>
00015 #include "struct.h"           /* general structures    */
00016 #include "..\common\postprocess\ximage.h"
00017 #include "local.h"
00018 #include "defines.h"
00019 
00020 #include "atmos.h"
00021 
00022 #if __X__MIPS__
00023 BOOL WINAPI _CRT_INIT(HINSTANCE ,DWORD , LPVOID );
00024 #endif
00025 
00026 static HINSTANCE hDLLinstance=NULL; /* use to pick up resources from DLL   */
00027 static long version=1;
00028 
00029 /************************** Local Utility Functions ***********************/
00030 
00031 #include "utils.h"
00032 #include "paint.c"
00033 
00034 /************************** DLL entry point ********************************/
00035 
00036 #if __WATCOMC__
00037 int APIENTRY LibMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00038 #elif __BC__
00039 BOOL WINAPI DllEntryPoint(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00040 #else
00041 BOOL WINAPI DllMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00042 #endif
00043   switch (dwReason) {
00044     case DLL_PROCESS_ATTACH:
00045 #if __X__MIPS__
00046       if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00047 #endif
00048       hDLLinstance = hDLL;  /* handle to DLL file */
00049       break;
00050     case DLL_PROCESS_DETACH:
00051 #if __X__MIPS__
00052       if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00053 #endif
00054       break;
00055   }
00056 return (int)TRUE;
00057 }
00058 
00059 #if __SC__
00060 #pragma startaddress(DllMain)
00061 #endif
00062 
00063 #define RS              (1.0/(double)RAND_MAX)
00064 #define CF(c)           ((double)(c)/(double)(255))
00065 #define VECCOPY(a,b)    { b[0] = a[0]; b[1] = a[1]; b[2] = a[2]; }
00066 #define INVERT(a)       { a[0] = -a[0]; a[1] = -a[1]; a[2] = -a[2]; }
00067 #define VECSUB(a,b,c)   { c[0]=a[0]-b[0]; c[1]=a[1]-b[1]; c[2]=a[2]-b[2];}
00068 #define VECSUM(a,b,c)   { c[0]=a[0]+b[0]; c[1]=a[1]+b[1]; c[2]=a[2]+b[2];}
00069 #define VECSCALE(a,b,c) { c[0]=(a)*b[0]; c[1]=(a)*b[1]; c[2]=(a)*b[2];}
00070 #define DOT(a,b)        ( (a[0]*b[0]) + (a[1]*b[1]) + (a[2]*b[2]) )
00071 #define CROSS(v1,v2,r)  { \
00072                           r[0] = (v1[1]*v2[2]) - (v2[1]*v1[2]);  \
00073                           r[1] = (v1[2]*v2[0]) - (v1[0]*v2[2]);  \
00074                           r[2] = (v1[0]*v2[1]) - (v2[0]*v1[1]);  \
00075                         }
00076 #define ONE_256 3.90625e-3
00077 
00078 static vector fog_colour={0.5,0.2,1.0};
00079 static double over_shadow=0.0,over_density=0.0,max_attn1=0.96;
00080 
00081 static void m4by1(double t4[4][4], double x, double y, double z,
00082                   double *xx, double *yy, double *zz){
00083    *xx=t4[0][0]*x+t4[0][1]*y+t4[0][2]*z+t4[0][3];
00084    *yy=t4[1][0]*x+t4[1][1]*y+t4[1][2]*z+t4[1][3];
00085    *zz=t4[2][0]*x+t4[2][1]*y+t4[2][2]*z+t4[2][3];
00086  return;
00087 }
00088 
00089 static double GetClosestPoint(vector d, vector P, vector r,
00090                               double *mu, double *lambda){
00091   vector a,x;
00092   double ddotr,pdotd,pdotr;
00093   ddotr=DOT(d,r);
00094   if(fabs(ddotr) < 1.0e-10){
00095     *mu = *lambda = 0.0; return 0.0;   // colinear;
00096   }
00097   pdotd=DOT(P,d);
00098   pdotr=DOT(P,r);
00099   *mu = (pdotd - pdotr*ddotr)/(1.0 - ddotr*ddotr);
00100   *lambda = *mu*ddotr-pdotr;
00101   VECSCALE(*mu,d,a)
00102   VECSUM(P,*lambda*r,x)
00103   VECSUB(a,x,a)
00104   return sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]);
00105 }
00106 
00107 static long GetSphereIntersection(vector d, vector P,
00108                                 double radius,
00109                                 double *dn, double *df){
00110  double ddotr,pdotr,a,a2,b,c,b4,mu1,mu2,lambda1,lambda2;
00111  vector A,B,tv;
00112  a=1.0;
00113  b=-2*(DOT(d,P));
00114  c=DOT(P,P)-radius*radius;
00115  b4=b*b-4.0*a*c;
00116  if(b4 < 0.0)return 0;
00117  else if(b4 < 1.e-10){
00118    *dn = *df = -b/(2*a);
00119  }
00120  else{
00121    b4=sqrt(b4);
00122    a2=0.5/a;
00123    mu1=(-b+b4)*a2;
00124    mu2=(-b-b4)*a2;
00125    if(mu1 < 0.0){
00126      *dn=0.0; *df=mu2;
00127    }
00128    else if(mu2 < 0){
00129      *dn=0.0; *df=mu1;
00130    }
00131    else{
00132      if(mu1 < mu2){*dn=mu1; *df=mu2;}
00133      else         {*dn=mu2; *df=mu1;}
00134    }
00135  }
00136  return 2;
00137 }
00138 
00139 static long GetConeIntersection(vector d,            // direction of ray
00140                                 vector P, vector r,  // light pos + direction
00141                                 double tt2,
00142                                 BOOL bOriginInCone,  // double cone
00143                                 BOOL bIlluminated,   // origin in ill. half
00144                                 double *dn, double *df){
00145  double ddotr,pdotr,a,a2,b,c,b4,mu1,mu2,lambda1,lambda2;
00146  vector A,B,tv;
00147  ddotr=DOT(d,r);
00148  VECSCALE(-ddotr,r,tv)
00149  VECSUM(d,tv,A)
00150  pdotr=DOT(P,r);
00151  VECSCALE(pdotr,r,tv)
00152  VECSUB(tv,P,B)
00153  a=DOT(A,A)-ddotr*ddotr*tt2;
00154  b=2*(DOT(A,B)+ddotr*pdotr*tt2);
00155  c=DOT(B,B)-pdotr*pdotr*tt2;
00156  b4=b*b-4.0*a*c;
00157  if(b4 < 0.0)return 0;     // no intersection of ray with cone
00158  else if(b4 < 1.e-10){     // one intersection
00159    *dn = -b/(2*a);
00160    lambda1=(*dn)*ddotr-pdotr;
00161    if(lambda1 < 0.0)return 0;
00162    *df = FARAWAY;
00163 MessageBeep(MB_OK);
00164    return 0; // 2
00165  }
00166  else{
00167    b4=sqrt(b4);
00168    a2=0.5/a;
00169    mu1=(-b+b4)*a2;
00170    mu2=(-b-b4)*a2;
00171    lambda1=mu1*ddotr-pdotr;
00172    lambda2=mu2*ddotr-pdotr;
00173    if(!bOriginInCone){ // ray originates outside cone
00174      if(lambda1 < 0.0 && lambda2 < 0.0)return 0;
00175      else if(lambda1 < 0.0){
00176        if(mu2 < 0)return 0;
00177        *dn=mu2; *df=FARAWAY;
00178      }
00179      else if(lambda2 < 0.0){
00180        if(mu1 < 0)return 0;
00181        *dn=mu1; *df=FARAWAY;
00182      }
00183      else{
00184        if(mu1 < 0.0 || mu2 < 0.0)return 0;
00185        if(mu1 < mu2){*dn=mu1; *df=mu2;}
00186        else         {*dn=mu2; *df=mu1;}
00187      }
00188    }
00189    else{  // ray originates inside cone
00190      if(lambda1 < 0.0 && lambda2 < 0.0)return 0;  // no inter with illuminate half
00191      else if(lambda1 < 0.0){  // dark half
00192        if(bIlluminated){
00193          *dn=1.0;
00194          *df=mu2;
00195        }
00196        else{
00197          if(mu2 < 0)*dn=1.0;    // light behind
00198          else       *dn=mu2;
00199         *df=FARAWAY;
00200        }
00201      }
00202      else if(lambda2 < 0.0){  // dark half
00203        if(bIlluminated){
00204          *dn=1.0;
00205          *df=mu1;
00206        }
00207        else{
00208          if(mu1 < 0)*dn=1.0;
00209          else       *dn=mu1;
00210          *df=FARAWAY;
00211        }
00212      }
00213      else{
00214        if(mu1 < mu2){
00215          if(mu1 < 0.0)*dn=1.0;
00216          else         *dn=mu1;
00217          *df=mu2;
00218        }
00219        else{
00220          if(mu2 < 0.0)*dn=1.0;
00221          else         *dn=mu2;
00222          *df=mu1;
00223        }
00224      }
00225    }
00226  }
00227  return 2;
00228 }
00229 
00230 static double m_ratio=1.0;
00231 
00232 static void TraceSphericalVolume(long Nsamples, vector d, vector pLight,
00233                                  double dns, double z, double dfs,
00234                                  double attn, vector colour,
00235                                  light *Lp, XIMAGE *lpXimage){
00236  double f;
00237  f = attn*(dfs-dns)/(2.0/Lp->dc_l);
00238  colour[0] = colour[0]*(1.0-f) + fog_colour[0]*f;
00239  colour[1] = colour[1]*(1.0-f) + fog_colour[1]*f;
00240  colour[2] = colour[2]*(1.0-f) + fog_colour[2]*f;
00241  return;
00242 }
00243 
00244 static void SimpleTrace(long type, double l, double lambda,
00245                         double dmin, double z, double dmax,
00246                         double tan_theta1, double tan_theta2,
00247                         double attn, vector colour,
00248                         light *Lp, XIMAGE *lpXimage){
00249  double tan_theta,f,noise,dattn;
00250  double noise1,noise2;
00251  if(lambda < 1.0e-10)return;
00252  tan_theta=l/lambda;
00253  if(z < dmax){
00254    attn = attn*(z-dmin)/(dmax-dmin);
00255  }
00256  noise1=Lp->pin[0]+Lp->pin[1]+Lp->pin[2];
00257  noise1 *= 0.33/12000.0;
00258  noise2=Lp->dPhi+Lp->dTheta+Lp->dAlpha;
00259  noise2 *= 0.33;
00260  if(type < 3){
00261    if(type == 0){
00262      noise=tan_theta*90.0; dattn=0.1;  // streaks
00263    }
00264    else if(type == 1){
00265      noise=l; dattn=0.3;               // particulate
00266    }
00267    else if(type == 2){
00268      noise = lambda/500.0;  dattn=0.1; // bands
00269    }
00270    nNoise(noise,noise1,noise2,&noise);
00271    attn += dattn*(noise-0.5);
00272    if(tan_theta <= tan_theta2){
00273      f=1.0 - (tan_theta/tan_theta2)*(tan_theta/tan_theta2);
00274      f=max(0.0,attn)*f;
00275    }
00276    else f=0.0;
00277  }
00278  else{
00279    attn=0.5; dattn=0.3;                // cloudy
00280    nNoise(l/12000.0,lambda/12000.0,0.0,&noise);
00281    attn += dattn*(noise-0.5);
00282    if(tan_theta <= tan_theta1)f=attn;
00283    else if(tan_theta <= tan_theta2){
00284      f=(1.0-(tan_theta-tan_theta1)/(tan_theta2-tan_theta1));
00285      f=attn*f;
00286    }
00287    else f=0.0;
00288  }
00289  colour[0] = colour[0]*(1.0-f) + fog_colour[0]*f;
00290  colour[1] = colour[1]*(1.0-f) + fog_colour[1]*f;
00291  colour[2] = colour[2]*(1.0-f) + fog_colour[2]*f;
00292  return;
00293 // if(tan_theta <= tan_theta1)f=attn;
00294 // else if(tan_theta <= tan_theta2){
00295 //   f=(1.0-(tan_theta-tan_theta1)/(tan_theta2-tan_theta1));
00296 //   f=attn*f;
00297 // }
00298 }
00299 
00300 static double PointInShadow(vector p, light *Lp, long SBS, XIMAGE *lpXimage){
00301   //  double shadow_density = -0.2;
00302   double shadow_density = -over_shadow;
00303   double intensity=1.0;
00304   double x,y,z,zz,dx,dy,ddx,ddy;
00305   long i,j;
00306   m4by1(Lp->shadow_transform,p[0],p[1],p[2],&x,&y,&z);
00307   if(y > 0.0){  /* point in front of light */
00308     ddx=Lp->scale*x/y;
00309     ddy=Lp->scale*z/y;
00310     dx=((double)SBS/2.0 + ddx);
00311     dy=((double)SBS/2.0 - ddy);
00312     //i=(long)dx; j=(long)dy;
00313     for(i=(long)dx-2;i<=(long)dx+1;i++)
00314     for(j=(long)dy-1;j<=(long)dy+2;j++)
00315     if(i >= 0 && i < SBS && j >= 0 && j < SBS){
00316       zz = *(Lp->atmospheric_shadow_buffer+j*SBS+i);
00317       if(y > zz)return shadow_density;
00318     }
00319     { double noise,noise1,noise2,r;
00320       r=2.0*sqrt(ddx*ddx+ddy*ddy)/(double)SBS;
00321       noise=10.0*r;
00322       noise1=Lp->pin[0]+Lp->pin[1]+Lp->pin[2];
00323       noise1 *= 0.33/12000.0;
00324       noise2=Lp->dPhi+Lp->dTheta+Lp->dAlpha;
00325       noise2 *= 0.33;
00326       nNoise(noise,noise1,noise2,&noise);
00327       intensity = 0.8+0.4*(noise-0.5);
00328     }
00329   }
00330   return intensity;
00331 }
00332 
00333 static void TracePixel(long Nsamples, long x, long y,
00334                        double dmin, double z, double dmax,
00335                        vector d, vector colour,
00336                        light *Lp, XIMAGE *lpXimage){
00337  double max_attn=max_attn1;
00338  long i;
00339  double ds,f,attn,attn1,alpha,cc,falloff;
00340  vector p,dp,dd,dl;
00341  ds=(dmax-dmin);
00342  if(z < dmax){
00343    max_attn = max_attn*(z-dmin)/ds;
00344    dmax=min(z,dmax);
00345    ds=(dmax-dmin);
00346  }
00347  ds=ds/(double)Nsamples;
00348  VECSCALE(dmin,d,p)
00349  VECSCALE(ds,d,dd);
00350  for(i=0,attn=0.0;i<Nsamples;i++){
00351    VECSCALE(ds*(double)rand()*RS,d,dp) VECSUM(dp,p,dp)
00352    attn1=PointInShadow(dp,Lp,lpXimage->shadow_buffer_size,lpXimage);
00353    //   if(attn1 > 0){f=0.8; goto TSST;}
00354    //   attn1=PointInShadow(p,Lp,lpXimage->shadow_buffer_size,lpXimage);
00355    //   if(PointInShadow(p,Lp,lpXimage->shadow_buffer_size,lpXimage) < 1.0)return;
00356    if(attn1 > 0.0){
00357      VECSUB(Lp->p,p,dl)
00358      normalize(dl);
00359      alpha=(fabs(DOT(Lp->d,dl)));
00360      if(alpha < Lp->dot2)falloff=0.0;
00361      else if(alpha < Lp->dot1)
00362        falloff=(alpha-Lp->dot2)*Lp->falloff;
00363      else falloff=1.0;
00364      attn1 *= falloff;
00365    }
00366    attn += attn1;
00367    VECSUM(p,dd,p)
00368  }
00369  attn=max(attn,0.0);
00370  f=max_attn*attn/(double)Nsamples;
00371  //f=min(1.0,f*4);
00372  f=min(1.0,f*over_density);
00373  //TSST:
00374  colour[0] = colour[0]*(1.0-f) + fog_colour[0]*f;
00375  colour[1] = colour[1]*(1.0-f) + fog_colour[1]*f;
00376  colour[2] = colour[2]*(1.0-f) + fog_colour[2]*f;
00377  return;
00378 }
00379 
00380 long _RenderImageProcess(char *PrmList, XIMAGE *lpXimage){
00381  int i,j,k;
00382  unsigned char cR,cG,cB;
00383  int icR,icG,icB;
00384  long fast,fast_type;
00385  char dummy[255];
00386  double tan_theta1,tan_theta2,cos_theta2;
00387  double Sx,Sy,dn,df,dns,dfs,dmin,dmax,l,mu,lambda;
00388  long Xmax,Ymax,type,id,nc,Nsamples=16;
00389  light *Lp;
00390  BOOL bOriginInCone,bIlluminated;
00391  vector d,dl,colour,phat;
00392  double tan_theta_sq;
00393  float *Zb;
00394  double z;
00395  fullscreenbuffer *S,*s;
00396  if(lpXimage->Nlights == 0 || lpXimage->Lights == NULL)return 1;
00397  sscanf(PrmList,"%s %ld %ld %ld %ld %ld %ld %d %d %d %f %f %f",
00398         dummy,
00399         &version,&type,&id,
00400         &Nsamples,&fast,&fast_type,
00401         &icR,&icG,&icB,
00402         &over_shadow,&over_density,&max_attn1);
00403  cR = (unsigned char)icR; 
00404  cG = (unsigned char)icG; 
00405  cB = (unsigned char)icB; 
00406  fog_colour[0]=CF(cR);
00407  fog_colour[1]=CF(cG);
00408  fog_colour[2]=CF(cB);
00409  over_density += 1;
00410  over_density=min(over_density,5.0);
00411  over_shadow=max(over_shadow,0.0);
00412  over_shadow=min(over_shadow,1.0);
00413  if(lpXimage->Morph && lpXimage->mParameters != NULL){
00414    m_ratio=lpXimage->MorphRatio;
00415    //sscanf(lpXimage->mParameters,"%s %ld",dummy,&version);
00416  }
00417  else{
00418    m_ratio=(double)(lpXimage->last_frame - lpXimage->first_frame);
00419    if(m_ratio < 1.0)m_ratio=1.0;
00420    else m_ratio=(double)(lpXimage->this_frame - lpXimage->first_frame)/m_ratio;
00421  }
00422  Zb=lpXimage->Zbuffer;
00423  S=lpXimage->Screen;
00424  Xmax=lpXimage->Xmax;
00425  Ymax=lpXimage->Ymax;
00426  Sx=lpXimage->Xscale;
00427  Sy=lpXimage->Yscale;
00428  for(k=0;k<lpXimage->Nlights;k++){
00429    Lp=(lpXimage->Lights+k);
00430    if(type == 2 && Lp->type != DUMMYL)continue;
00431    if(type == 3 && Lp->AnimatorID != id)continue;
00432    //SetShadowBuffer(325000.0,Lp,lpXimage);
00433    //SetShadowBuffer(200.0,Lp,lpXimage);
00434    if(Lp->type != SPOTLIGHT){ // non spots can only do if falloff
00435      if(Lp->dc){              // light fall off
00436        for(j=0;j<Ymax;j++){
00437          lpXimage->fp_Yield();
00438          if((lpXimage->fp_Terminate()) < 0)goto XXIT;
00439          for(i=0;i<Xmax;i++){
00440            d[2] = -((double)j + 0.5 - (double)Ymax/2.0)/Sy;
00441            d[0] =  ((double)i + 0.5 - (double)Xmax/2.0)/Sx;
00442            d[1] =  1.0;
00443            normalize(d);
00444            nc=GetSphereIntersection(d,Lp->p,1.0/Lp->dc_l,&dns,&dfs);
00445            if(nc > 1){  // inside sphere as well
00446              z = (double)(*(Zb + (j*Xmax)+i))/d[1];
00447              if(dns < z){
00448                s = (S+(j*Xmax)+i);
00449                colour[0]=ONE_256*(double)s->R;
00450                colour[1]=ONE_256*(double)s->G;
00451                colour[2]=ONE_256*(double)s->B;
00452                TraceSphericalVolume(Nsamples,d,Lp->p,dns,z,dfs,1.0,colour,Lp,lpXimage);
00453                s->R=(unsigned char)min(255L,(long)(256.0*colour[0]));
00454                s->G=(unsigned char)min(255L,(long)(256.0*colour[1]));
00455                s->B=(unsigned char)min(255L,(long)(256.0*colour[2]));
00456              }
00457            }
00458          }
00459        }
00460      }
00461    }
00462    else{  // spotlights only
00463      tan_theta1=tan(Lp->cone1-2.0*PI/180.0);
00464      tan_theta2=tan(Lp->cone2);
00465      cos_theta2=cos(Lp->cone2);
00466      tan_theta_sq=tan_theta2*tan_theta2;
00467      VECSCALE(-1.0,Lp->d,dl) // to point in direction of shine!
00468      VECCOPY(Lp->p,phat)
00469      normalize(phat);
00470      z=DOT(dl,phat);
00471      if(z > 0)bIlluminated=FALSE;
00472      else     bIlluminated=TRUE;
00473      if(fabs(z) > cos_theta2)bOriginInCone=TRUE;
00474      else                    bOriginInCone=FALSE;
00475      for(j=0;j<Ymax;j++){
00476        lpXimage->fp_Yield();
00477        if((lpXimage->fp_Terminate()) < 0)goto XXIT;
00478        for(i=0;i<Xmax;i++){
00479          d[2] = -((double)j + 0.5 - (double)Ymax/2.0)/Sy;
00480          d[0] =  ((double)i + 0.5 - (double)Xmax/2.0)/Sx;
00481          d[1] =  1.0;
00482          normalize(d);
00483          dmin=FARAWAY; dmax=0.0;
00484          nc=GetConeIntersection(d,Lp->p,dl,
00485                                 tan_theta_sq,bOriginInCone,bIlluminated,
00486                                 &dn,&df);
00487          if(nc > 0){
00488            if(dn < dmin)dmin=dn;
00489            if(df > dmax)dmax=df;
00490            if(dmax > FARAWAY-100.0)dmax=1.0e9;
00491            // since Z buffer is DEPTH not distance the "z" value must
00492            // be adjusted from depth to distance
00493            z = (double)(*(Zb + (j*Xmax)+i))/d[1];
00494            if(dmin < z){  // some light visible
00495              s = (S+(j*Xmax)+i);
00496              colour[0]=ONE_256*(double)s->R;
00497              colour[1]=ONE_256*(double)s->G;
00498              colour[2]=ONE_256*(double)s->B;
00499              if(fast == 1){  // aprox or full integration
00500                l=GetClosestPoint(d,Lp->p,dl,&mu,&lambda);
00501                SimpleTrace(fast_type,l,lambda,dmin,z,dmax,
00502                            tan_theta1,tan_theta2,
00503                            min(max_attn1,0.4),colour,Lp,lpXimage);  // max_attn1 0.4
00504              }
00505              else TracePixel(Nsamples,i,j,dmin,z,dmax,d,colour,Lp,lpXimage);
00506              s->R=(unsigned char)min(255L,(long)(256.0*colour[0]));
00507              s->G=(unsigned char)min(255L,(long)(256.0*colour[1]));
00508              s->B=(unsigned char)min(255L,(long)(256.0*colour[2]));
00509            }
00510          }
00511        }
00512      }
00513    }
00514  }
00515  XXIT:
00516  return 1;
00517 }
00518 
00519 long _RenderGLexternal(char *PrmList, XIMAGE *lpXimage){
00520  return 1;
00521 }
00522 
00523 BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam);
00524 
00525 
00526 static long type=1,id = -1,samp=16,fast=0,fast_type=0;
00527 static unsigned char cR=255,cG=255,cB=255;
00528 static X__MEMORY_MANAGER *lpLocalEVI;
00529 
00530 char * _SetExternalParameters(
00531   char *Op,                 /* string for the parameters                  */
00532   HWND hWnd,                /* parent window                              */
00533   long ruler,               /* ruler scale value to facilitate scaling    */
00534   char *name,               /* name of DLL file with the effect           */
00535   X__MEMORY_MANAGER *lpEVI /* pointer to structure with memory functions */
00536                                     ){
00537  /* output name and buffer should be as long as necessary to hold full string */
00538  char buffer[256];
00539  int icR,icG,icB;
00540  if(Op != NULL){  /* parameters exist so read them off the list */
00541    sscanf(Op,"%s %ld %ld %ld %ld %ld %ld %d %d %d %f %f %f",
00542           buffer,&version,&type,&id,
00543           &samp,&fast,&fast_type,&icR,&icG,&icB,
00544           &over_shadow,&over_density,&max_attn1);
00545    cR = (unsigned char)icR; 
00546    cG = (unsigned char)icG; 
00547    cB = (unsigned char)icB; 
00548  }
00549  lpLocalEVI=lpEVI;
00550  if(DialogBox(hDLLinstance,MAKEINTRESOURCE(DLG_ATMOS),hWnd,
00551               (DLGPROC)DlgProc) == FALSE)return Op;
00552  if(Op != NULL)CALL_FREE(Op);  /* free the old string */
00553  sprintf(buffer,"%s %ld %ld %ld %ld %ld %ld %ld %ld %ld %f %f %f",
00554          name,version,type,id,
00555          samp,fast,fast_type,cR,cG,cB,
00556          over_shadow,over_density,max_attn1);
00557  if((Op=(char *)CALL_MALLOC(strlen(buffer)+1)) == NULL){
00558    return NULL;
00559  }
00560  strcpy(Op,buffer);
00561  return Op;
00562 }
00563 
00564 static void SetColour(unsigned char *colour, HWND parent){
00565  CHOOSECOLOR cc;
00566  static COLORREF CustColours[16]={
00567    RGB(255,255,255), RGB(239,239,239), RGB(223,223,223), RGB(207,207,207),
00568    RGB(191,191,191), RGB(175,175,175), RGB(159,159,159), RGB(143,143,143),
00569    RGB(127,127,127), RGB(111,111,111), RGB( 95, 95, 95), RGB( 79, 79, 79),
00570    RGB( 63, 63, 63), RGB( 47, 47, 47), RGB( 31, 31, 31), RGB( 15, 15, 15) };
00571  cc.lStructSize=sizeof(CHOOSECOLOR);
00572  cc.hwndOwner=parent;
00573  cc.rgbResult=RGB((BYTE)colour[0],(BYTE)colour[1],(BYTE)colour[2]);
00574  cc.lpCustColors=(LPDWORD)CustColours;
00575  cc.Flags= CC_RGBINIT;
00576  cc.lCustData=(DWORD)0;
00577  if(ChooseColor(&cc)){
00578    colour[0]=(unsigned char)GetRValue(cc.rgbResult);
00579    colour[1]=(unsigned char)GetGValue(cc.rgbResult);
00580    colour[2]=(unsigned char)GetBValue(cc.rgbResult);
00581  }
00582 }
00583 
00584 static void LoadAnimatedClip(HWND hDlg){
00585  char *c,modname[256];
00586  GetModuleFileName(hDLLinstance,modname,255);
00587  if((c=strrchr(modname,'.')) != NULL){
00588    strcpy(c,".avi");
00589    Animate_Open(GetDlgItem(hDlg,DLG_IMAGE),modname);
00590    Animate_Play(GetDlgItem(hDlg,DLG_IMAGE),0, -1, -1);
00591  }
00592 }
00593 
00594 BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam){
00595  char str[32];
00596  switch( msg ) {
00597    case WM_INITDIALOG:
00598      sprintf(str,"%.3f",over_shadow);
00599      SetDlgItemText(hwnd,DLG_ATMOS_OVERSHADOW,str);
00600      sprintf(str,"%.3f",over_density);
00601      SetDlgItemText(hwnd,DLG_ATMOS_OVERDENSITY,str);
00602      sprintf(str,"%.3f",max_attn1);
00603      SetDlgItemText(hwnd,DLG_ATMOS_MAXATTN,str);
00604      sprintf(str,"%ld",samp);
00605      SetDlgItemText(hwnd,DLG_ATMOS_SAMPLES,str);
00606 
00607      if(fast == 1)SendDlgItemMessage(hwnd,DLG_ATMOS_FAST,BM_SETCHECK,TRUE,0);
00608      if(fast_type == 0)SendDlgItemMessage(hwnd,DLG_ATMOS_FAST1,BM_SETCHECK,TRUE,0);
00609      if(fast_type == 1)SendDlgItemMessage(hwnd,DLG_ATMOS_FAST2,BM_SETCHECK,TRUE,0);
00610      if(fast_type == 2)SendDlgItemMessage(hwnd,DLG_ATMOS_FAST3,BM_SETCHECK,TRUE,0);
00611      if(fast_type == 3)SendDlgItemMessage(hwnd,DLG_ATMOS_FAST4,BM_SETCHECK,TRUE,0);
00612 
00613      if(type == 1)SendDlgItemMessage(hwnd,DLG_ATMOS_TYPE1,BM_SETCHECK,TRUE,0);
00614      if(type == 2)SendDlgItemMessage(hwnd,DLG_ATMOS_TYPE2,BM_SETCHECK,TRUE,0);
00615      if(type == 3)SendDlgItemMessage(hwnd,DLG_ATMOS_TYPE3,BM_SETCHECK,TRUE,0);
00616      if(id >= 0)SendDlgItemMessage(hwnd,DLG_ATMOS_NAME,WM_SETTEXT,
00617                 0,(LPARAM)GetActorsName(lpLocalEVI->lpAni,id));
00618 
00619  //    LoadAnimatedClip(hwnd);
00620      CentreDialogOnScreen(hwnd);
00621      return TRUE;
00622    case WM_PAINT:
00623      PaintBackground(hwnd);
00624      break;
00625    case WM_DRAWITEM:{
00626        LPDRAWITEMSTRUCT lpdis;
00627        HBRUSH   hbr,hbrold;
00628        BYTE r,g,b;
00629        lpdis=(LPDRAWITEMSTRUCT)lparam;
00630        if(lpdis->CtlID == DLG_ATMOS_COLOUR){
00631          r=cR; g=cG; b=cB;
00632          if(lpdis->itemState & ODS_SELECTED)
00633             InvertRect(lpdis->hDC,&(lpdis->rcItem));
00634          else{
00635            hbr=CreateSolidBrush(RGB(r,g,b));
00636            hbrold=SelectObject(lpdis->hDC,hbr);
00637            Rectangle(lpdis->hDC,lpdis->rcItem.left,lpdis->rcItem.top,
00638                          lpdis->rcItem.right,lpdis->rcItem.bottom);
00639            SelectObject(lpdis->hDC,hbrold);
00640            DeleteObject(hbr);
00641          }
00642        }
00643      }
00644      break;
00645    case WM_COMMAND:
00646      switch(LOWORD(wparam)){
00647         case DLG_ATMOS_COLOUR:{
00648             unsigned char colour[3];
00649             colour[0]=cR; colour[1]=cG; colour[2]=cB;
00650             SetColour(colour,hwnd);
00651             cR=colour[0]; cG=colour[1]; cB=colour[2];
00652             InvalidateRect(GetDlgItem(hwnd,DLG_ATMOS_COLOUR),NULL,FALSE);
00653           }
00654           break;
00655         case DLG_ATMOS_SETID:
00656           id=GetActorsID(lpLocalEVI->lpAni,hwnd);
00657           if(id >= 0)SendDlgItemMessage(hwnd,DLG_ATMOS_NAME,WM_SETTEXT,
00658                      0,(LPARAM)GetActorsName(lpLocalEVI->lpAni,id));
00659           break;
00660         case IDCANCEL:
00661           EndDialog(hwnd,FALSE);
00662           return(TRUE);
00663         case IDOK:
00664           if(GetDlgItemText(hwnd,DLG_ATMOS_OVERSHADOW,str,12) != 0)
00665             sscanf(str,"%f",&over_shadow);
00666           if(GetDlgItemText(hwnd,DLG_ATMOS_OVERDENSITY,str,12) != 0)
00667             sscanf(str,"%f",&over_density);
00668           if(GetDlgItemText(hwnd,DLG_ATMOS_MAXATTN,str,12) != 0)
00669             sscanf(str,"%f",&max_attn1);
00670           if(GetDlgItemText(hwnd,DLG_ATMOS_SAMPLES,str,12) != 0)
00671             sscanf(str,"%ld",&samp);
00672 
00673           if(SendDlgItemMessage(hwnd,DLG_ATMOS_FAST,BM_GETCHECK,0,0))fast=1;
00674           else                                                       fast=0;
00675           if(SendDlgItemMessage(hwnd,DLG_ATMOS_FAST1,BM_GETCHECK,0,0))fast_type=0;
00676           if(SendDlgItemMessage(hwnd,DLG_ATMOS_FAST2,BM_GETCHECK,0,0))fast_type=1;
00677           if(SendDlgItemMessage(hwnd,DLG_ATMOS_FAST3,BM_GETCHECK,0,0))fast_type=2;
00678           if(SendDlgItemMessage(hwnd,DLG_ATMOS_FAST4,BM_GETCHECK,0,0))fast_type=3;
00679 
00680           if(SendDlgItemMessage(hwnd,DLG_ATMOS_TYPE1,BM_GETCHECK,0,0))type=1;
00681           if(SendDlgItemMessage(hwnd,DLG_ATMOS_TYPE2,BM_GETCHECK,0,0))type=2;
00682           if(SendDlgItemMessage(hwnd,DLG_ATMOS_TYPE3,BM_GETCHECK,0,0))type=3;
00683           EndDialog(hwnd,TRUE);
00684           return(TRUE);
00685         default:
00686           break;
00687       }
00688       break;
00689     default: break;
00690  }
00691  return FALSE;
00692 }
00693 
00694 //static void TracePixel0(long Nsamples, long x, long y,
00695 //                       double dmin, double z, double dmax,
00696 //                       vector d, vector colour,
00697 //                       light *Lp, XIMAGE *lpXimage){
00698 // colour[0] += 0.25;
00699 // colour[1] += 0.25;
00700 // colour[2] += 0.25;
00701 // return;
00702 //}
00703 
00704 //static BOOL RenderShadow(long Nsamples, long x, long y,
00705 //                       double dmin, double z, double dmax,
00706 //                       vector d, vector colour,
00707 //                       light *Lp, XIMAGE *lpXimage){
00708 // double zz;
00709 // long SBS;
00710 // SBS=lpXimage->shadow_buffer_size;
00711 // if(x >= 0 && x < SBS && y >= 0 && y < SBS){
00712 //   zz = *(Lp->atmospheric_shadow_buffer+y*SBS+x);
00713 //   if(zz < FARAWAY-100.0){colour[0]=colour[1]=colour[2]=1.0;}
00714 //   else                  {colour[0]=colour[1]=colour[2]=0.0;}
00715 //   return TRUE;
00716 // }
00717 // return FALSE;
00718 //}
00719 
00720 //void SetShadowBuffer(double v, light *Lp, XIMAGE *lpXimage){
00721 // double zz;
00722 // long i,j,SBS,nd,dd,x0,y0;
00723 // SBS=lpXimage->shadow_buffer_size;
00724 // for(i=0;i<SBS;i++)for(j=0;j<SBS;j++){
00725 //#if 1
00726 //  *(Lp->atmospheric_shadow_buffer+i*SBS+j) = FARAWAY;  // for trellis
00727 //#elif 0
00728 //   if(i > SBS/4 && i < (SBS*3)/4 && j > SBS/4 && j < (SBS*3)/4){
00729 //     *(Lp->atmospheric_shadow_buffer+i*SBS+j) = v;
00730 //   }
00731 //   else *(Lp->atmospheric_shadow_buffer+i*SBS+j) = FARAWAY;
00732 //#else
00733 //   if(*(Lp->atmospheric_shadow_buffer+i*SBS+j) < v)
00734 //        *(Lp->atmospheric_shadow_buffer+i*SBS+j) = v;
00735 //   else *(Lp->atmospheric_shadow_buffer+i*SBS+j) = FARAWAY;
00736 //#endif
00737 // }
00738 //#if 1
00739 // dd=4;             // trellis
00740 // nd=SBS/(4*dd);
00741 // y0=nd;
00742 // for(i=0;i<dd;i++){
00743 //   x0=nd;
00744 //   for(j=0;j<dd;j++){
00745 //     long ii,jj;
00746 //     for(ii=y0;ii<y0+2*nd;ii++)for(jj=x0;jj<x0+2*nd;jj++){
00747 //         *(Lp->atmospheric_shadow_buffer+ii*SBS+jj) = v;
00748 //     }
00749 //     x0 += 4*nd;
00750 //   }
00751 //   y0 += 4*nd;
00752 // }
00753 //#endif
00754 // return;
00755 //}
00756 
00757 //         s = (S+(j*Xmax)+i);
00758 //         if(RenderShadow(16,i,j,dmin,z,dmax,d,colour,Lp,lpXimage)){
00759 //           s->R=(unsigned char)min(255L,(long)(256.0*colour[0]));
00760 //           s->G=(unsigned char)min(255L,(long)(256.0*colour[1]));
00761 //           s->B=(unsigned char)min(255L,(long)(256.0*colour[2]));
00762 //         }

Generated on Sun Apr 27 14:20:12 2014 for OpenFX by  doxygen 1.5.6