FOG.C

Go to the documentation of this file.
00001 /* --
00002 OpenFX version 2.0 - Modelling, Animation and Rendering Package
00003 Copyright (C) 2000 -  OpenFX Development Team
00004 -- */
00005 
00006 /* FOG.C  Image post-processor using Z buffer                            */
00007 /*                                                                       */
00008 /* Postprocessor showing the use of the Z buffer, user must have turned  */
00009 /* this on. If it is NOT available the Zbuffer pointer in the XIMAGE     */
00010 /* structure will be NULL. The user can set two distances between which  */
00011 /* the FOG wil go from zero attenuation to a preset value. A Haze option */
00012 /* automatically attenuates from full visibility at the camera to x% at  */
00013 /* farthest value in Z buffer. Z buffer distances are float values of    */
00014 /* World co-ordinates.                                                   */
00015 /*                                                                       */
00016 
00017 #include <stdlib.h>
00018 #include <stdio.h>
00019 #include <float.h>
00020 #include <math.h>
00021 #include <windows.h>
00022 #include <gl\gl.h>
00023 #include <gl\glu.h>
00024 #include "struct.h"           /* general structures    */
00025 #include "..\common\postprocess\ximage.h"
00026 #include "local.h"
00027 
00028 #include "fog.h"
00029 
00030 #if __X__MIPS__
00031 BOOL WINAPI _CRT_INIT(HINSTANCE ,DWORD , LPVOID );
00032 #endif
00033 
00034 static HINSTANCE hDLLinstance=NULL; /* use to pick up resources from DLL  */
00035 
00036 /************************** Local Utility Functions ***********************/
00037 
00038 #include "utils.h"
00039 #include "paint.c"
00040 
00041 /* utility function to set colour value */
00042 static void SetColour(unsigned char *colour, HWND parent){
00043  CHOOSECOLOR cc;
00044  static COLORREF CustColours[16]={
00045    RGB(255,255,255), RGB(239,239,239), RGB(223,223,223), RGB(207,207,207),
00046    RGB(191,191,191), RGB(175,175,175), RGB(159,159,159), RGB(143,143,143),
00047    RGB(127,127,127), RGB(111,111,111), RGB( 95, 95, 95), RGB( 79, 79, 79),
00048    RGB( 63, 63, 63), RGB( 47, 47, 47), RGB( 31, 31, 31), RGB( 15, 15, 15) };
00049  cc.lStructSize=sizeof(CHOOSECOLOR);
00050  cc.hwndOwner=parent;
00051  cc.rgbResult=RGB((BYTE)colour[0],(BYTE)colour[1],(BYTE)colour[2]);
00052  cc.lpCustColors=(LPDWORD)CustColours;
00053  cc.Flags= CC_RGBINIT;
00054  cc.lCustData=(DWORD)0;
00055  if(ChooseColor(&cc)){
00056    colour[0]=(unsigned char)GetRValue(cc.rgbResult);
00057    colour[1]=(unsigned char)GetGValue(cc.rgbResult);
00058    colour[2]=(unsigned char)GetBValue(cc.rgbResult);
00059  }
00060 }
00061 
00062 /************************** DLL entry point ********************************/
00063 
00064 #if __WATCOMC__
00065 int APIENTRY LibMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00066 #elif __BC__
00067 BOOL WINAPI DllEntryPoint(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00068 #else
00069 BOOL WINAPI DllMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00070 #endif
00071   switch (dwReason) {
00072     case DLL_PROCESS_ATTACH:
00073 #if __X__MIPS__
00074       if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00075 #endif
00076       hDLLinstance = hDLL;  /* handle to DLL file */
00077       break;
00078     case DLL_PROCESS_DETACH:
00079 #if __X__MIPS__
00080       if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00081 #endif
00082       break;
00083   }
00084 return (int)TRUE;
00085 }
00086 
00087 #if __SC__
00088 #pragma startaddress(DllMain)
00089 #endif
00090 
00091 /*******************************************************************\
00092 |                Code that executes the process                     |
00093 \*******************************************************************/
00094 
00095 
00096 long _RenderImageProcess(char *PrmList, XIMAGE *lpXimage){
00097  /* Z is UP, Y is forward (in front of observer, X to the RIGHT    */
00098  /* the camera is located at 0,0,0. All real numbers are floats    */
00099  /* xx and yy are screen co-ords of light (0,0) is at top left     */
00100  /* Zbuffer values are distances from Camera (at 0,0,0) to surface */
00101  /* visible in pixel. Z buffer addressing is similar to Screen     */
00102  /* buffer addressing.                                             */
00103  int i,j,ftype,id1,id2,idensity,cR,cG,cB;
00104  int mftype,midensity,mid1,mid2,mcR,mcG,mcB;
00105  double d1,d2,d12,density,density1,f,f1,zmax,zmin;
00106  double mr;
00107  char name_path[255];
00108  fullscreenbuffer *S;
00109  float *Z;
00110  BOOL bMorph;
00111  if((Z=lpXimage->Zbuffer) == NULL){
00112    MessageBox(GetFocus(),"Z buffer must be available for this effect",
00113               NULL,MB_OK);
00114    return 0;
00115  }
00116  sscanf(PrmList,"%s %d %d %d %d %d %d %d",name_path,&ftype,&idensity,
00117         &id1,&id2,&cR,&cG,&cB);
00118  if(lpXimage->Morph && lpXimage->mParameters != NULL){
00119    bMorph=TRUE; mr=lpXimage->MorphRatio;
00120    sscanf(lpXimage->mParameters,"%s %d %d %d %d %d %d %d",
00121           name_path,&mftype,&midensity,&mid1,&mid2,&mcR,&mcG,&mcB);
00122    id1=(long)((double)mid1 + mr*((double)id1-(double)mid1));
00123    id2=(long)((double)mid2 + mr*((double)id2-(double)mid2));
00124    idensity=(long)((double)midensity + mr*((double)idensity-(double)midensity));
00125    cR=(long)((double)mcR + mr*((double)cR-(double)mcR));
00126    cG=(long)((double)mcG + mr*((double)cG-(double)mcG));
00127    cB=(long)((double)mcB + mr*((double)cB-(double)mcB));
00128  }
00129  density=(double)idensity/100.0;
00130  density1=(1.0 - density);
00131  d1=(double)id1;
00132  d2=(double)id2;
00133  S=lpXimage->Screen;
00134  if(ftype == 0){ /* autoscaled haze    */
00135    zmin=FARAWAY; /* defined in utils.h */
00136    zmax=0.0;
00137    for(i=0;i<lpXimage->Ymax;i++){
00138      for(j=0;j<lpXimage->Xmax;j++){
00139        if(*Z < zmin)zmin = *Z;
00140        if(*Z > zmax && *Z < FARAWAY)zmax=*Z;
00141        Z++;
00142      }
00143    }
00144    Z=lpXimage->Zbuffer;  /* re-vector Z to start of buffer  */
00145    d1=zmin; d2=zmax;     /* set depth for this mist/haze    */
00146  }
00147  d12=density/(d2-d1);
00148 //{char ttt[256]; sprintf(ttt,"Image size %ld by %ld d1=%lf d2=%lf",lpXimage->Xmax,lpXimage->Ymax,d1,d2);
00149 //MessageBox(NULL,ttt,NULL,MB_OK);}
00150  for(i=0;i<lpXimage->Ymax;i++){
00151    for(j=0;j<lpXimage->Xmax;j++){
00152      if( *Z > d2){ /* total whiteout */
00153        S->R = (unsigned char)min(255.0,density*(double)cR+
00154                                       density1*(double)S->R);
00155        S->G = (unsigned char)min(255.0,density*(double)cG+
00156                                       density1*(double)S->G);
00157        S->B = (unsigned char)min(255.0,density*(double)cB+
00158                                       density1*(double)S->B);
00159      }
00160      else if( *Z > d1){ /* in the mist */
00161        f=(*Z - d1)*d12; f1=(1.0-f);
00162        S->R = (unsigned char)min(255.0,f*(double)cR+f1*(double)S->R);
00163        S->G = (unsigned char)min(255.0,f*(double)cG+f1*(double)S->G);
00164        S->B = (unsigned char)min(255.0,f*(double)cB+f1*(double)S->B);
00165      }
00166      S++; Z++;
00167    }
00168  }
00169  return 1;
00170 }
00171 
00172 /*************** Function that renders anyof the OpenGL Functionality ************/
00173 
00174 long _RenderGLexternal(char *PrmList, XIMAGE *lpXimage){
00175 //MessageBox(NULL,"Fog OpenGL function called","OK",MB_OK);
00176  return 1;
00177 }
00178 
00179 /*************** Functions used to setup      ***************/
00180 
00181 
00182 /* Dialog box callback  */
00183 BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam);
00184 
00185 static double   d1=2.0,d2=10.0;
00186 static int      ftype=0,density=80;
00187 static unsigned char colour[3]={255,255,255};
00188 
00189 char * _SetExternalParameters(
00190   char *Op,                 /* string for the parameters                  */
00191   HWND hWnd,                /* parent window                              */
00192   long ruler,               /* ruler scale value to facilitate scaling    */
00193   char *name,               /* name of DLL file with the effect           */
00194   X__MEMORY_MANAGER *lpEVI /* pointer to structure with memory functions */
00195                                     ){
00196  /* output name and buffer should be as long as necessary to hold full string */
00197  char buffer[256];
00198  long id1,id2;   /* integer scaled radius value */
00199  if(Op != NULL){  /* parameters exist so read them off the list */
00200    sscanf(Op,"%s %ld %ld %ld %ld %d %d %d",buffer,&ftype,&density,&id1,&id2,
00201           &colour[0],&colour[1],&colour[2]);
00202    d1=(double)id1/(double)ruler;
00203    d2=(double)id2/(double)ruler;
00204  }
00205  /*   Do the user interface as required to set up the effect, may use a     */
00206  /*   dialog box etc. Return old string if effect is cancelled (no change)  */
00207  if(DialogBox(hDLLinstance,MAKEINTRESOURCE(DLG_FOG),hWnd,
00208               (DLGPROC)DlgProc) == FALSE)return Op;
00209  /* Free space occupied by old parameter string */
00210  if(Op != NULL)CALL_FREE(Op);  /* free the old string */
00211  /* print the parameters into the buffer */
00212  id1=(long)(d1*(double)ruler);
00213  id2=(long)(d2*(double)ruler);
00214  sprintf(buffer,"%s %ld %ld %ld %ld %d %d %d",name,ftype,density,id1,id2,
00215            colour[0],colour[1],colour[2]);
00216  /* Prepare the output buffer to take copy of parameter list */
00217  if((Op=(char *)CALL_MALLOC(strlen(buffer)+1)) == NULL){
00218   MessageBox (GetFocus(),"External effect: Out of memory","Error",
00219                 MB_OK|MB_TASKMODAL|MB_ICONSTOP);
00220    return NULL;
00221  }
00222  /* Copy the parameter string to the output buffer */
00223  strcpy(Op,buffer);
00224  return Op;
00225 }
00226 
00227 BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam){
00228  /* a radius value of 1.0 will give a halo of radius 1.0  unit     */
00229  /* for whatever co-ordinate system is in use for this animation   */
00230  /* the size relative to the actors can be determined by using the */
00231  /* co-ord dialog to check on the size of the actors               */
00232  char str[32];
00233  switch( msg ) {
00234    case WM_INITDIALOG:
00235      if(ftype == 0)
00236        SendDlgItemMessage(hwnd,DLG_FOG_HAZE,BM_SETCHECK,TRUE,0);
00237      else
00238        SendDlgItemMessage(hwnd,DLG_FOG_FOG,BM_SETCHECK,TRUE,0);
00239      SetDlgItemInt(hwnd,DLG_FOG_DENSITY,(100-density),FALSE);
00240      sprintf(str,"%.2f",d1);
00241      SetDlgItemText(hwnd,DLG_FOG_D1,str);
00242      sprintf(str,"%.2f",d2);
00243      SetDlgItemText(hwnd,DLG_FOG_D2,str);
00244      CentreDialogOnScreen(hwnd);
00245      return TRUE;
00246    case WM_PAINT:
00247      PaintBackground(hwnd);
00248      break;
00249    case WM_DRAWITEM:{
00250        LPDRAWITEMSTRUCT lpdis;
00251        HBRUSH   hbr,hbrold;
00252        BYTE r,g,b;
00253        lpdis=(LPDRAWITEMSTRUCT)lparam;
00254        if(lpdis->CtlID == DLG_FOG_COLOUR){
00255          r=(BYTE)colour[0]; g=(BYTE)colour[1]; b=(BYTE)colour[2];
00256          if(lpdis->itemState & ODS_SELECTED)
00257             InvertRect(lpdis->hDC,&(lpdis->rcItem));
00258          else{
00259            hbr=CreateSolidBrush(RGB(r,g,b));
00260            hbrold=SelectObject(lpdis->hDC,hbr);
00261            Rectangle(lpdis->hDC,lpdis->rcItem.left,lpdis->rcItem.top,
00262                          lpdis->rcItem.right,lpdis->rcItem.bottom);
00263            SelectObject(lpdis->hDC,hbrold);
00264            DeleteObject(hbr);
00265          }
00266        }
00267      }
00268      break;
00269    case WM_COMMAND:
00270      switch(LOWORD(wparam)){
00271         case DLG_FOG_COLOUR:
00272           SetColour(colour,hwnd);
00273           InvalidateRect(GetDlgItem(hwnd,DLG_FOG_COLOUR),NULL,FALSE);
00274           break;
00275         case IDCANCEL:
00276           EndDialog(hwnd,FALSE);
00277           return(TRUE);
00278         case IDOK:
00279           if(SendDlgItemMessage(hwnd,DLG_FOG_FOG,BM_GETCHECK,0,0))
00280                ftype=1;
00281           else ftype=0;
00282           if(GetDlgItemText(hwnd,DLG_FOG_D1,str,12) != 0)d1=atof(str);
00283           if(GetDlgItemText(hwnd,DLG_FOG_D2,str,12) != 0)d2=atof(str);
00284           if(GetDlgItemText(hwnd,DLG_FOG_DENSITY,str,12) != 0)
00285             density=100-atoi(str);
00286           EndDialog(hwnd,TRUE);
00287           return(TRUE);
00288         default:
00289           break;
00290       }
00291       break;
00292     default: break;
00293  }
00294  return FALSE;
00295 }
00296 

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