ATMOS.C

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