HALO.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 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 /* halo.c  image post-processor                                         */
00025 /*                                                                      */
00026 /* This post-processor gives users the ability to add halos round light */
00027 /* sources. Normally lights are invisible in an animation but this      */
00028 /* process adds a halo round light sources, the size of halo is set by  */
00029 /* the user, because the size of the halo is constant it will appear    */
00030 /* to get smaller as a light moves away from the camera. Many more      */
00031 /* parameters could be added to this example, colour, transparency      */
00032 /* falloff, etc. If used with a Z buffer the light could pass behind    */
00033 /* other objects in the scene. Note that the position of lights has     */
00034 /* been transformed to camera co-ordinates before the image processor   */
00035 /* is loaded so there is no need to call TransformIntoView before       */
00036 /* using the components of the vector P. This examples is intended to   */
00037 /* show how access and use information in the light data structure.     */
00038 /*                                                                      */
00039 
00040 #include <stdlib.h>
00041 #include <stdio.h>
00042 #include <float.h>
00043 #include <math.h>
00044 #include <windows.h>
00045 #include "struct.h"           /* general structures    */
00046 #include "..\common\postprocess\ximage.h"
00047 #include "local.h"
00048 
00049 #include "halo.h"
00050 
00051 #if __X__MIPS__
00052 BOOL WINAPI _CRT_INIT(HINSTANCE ,DWORD , LPVOID );
00053 #endif
00054 
00055 static HINSTANCE hDLLinstance=NULL; /* use to pick up resources from DLL   */
00056 static long version=1;
00057 
00058 /************************** Local Utility Functions ***********************/
00059 
00060 #include "utils.h"
00061 #include "paint.c"
00062 
00063 /************************** DLL entry point ********************************/
00064 
00065 #if __WATCOMC__
00066 int APIENTRY LibMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00067 #elif __BC__
00068 BOOL WINAPI DllEntryPoint(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00069 #else
00070 BOOL WINAPI DllMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00071 #endif
00072   switch (dwReason) {
00073     case DLL_PROCESS_ATTACH:
00074 #if __X__MIPS__
00075       if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00076 #endif
00077       hDLLinstance = hDLL;  /* handle to DLL file */
00078       break;
00079     case DLL_PROCESS_DETACH:
00080 #if __X__MIPS__
00081       if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00082 #endif
00083       break;
00084   }
00085 return (int)TRUE;
00086 }
00087 
00088 #if __SC__
00089 #pragma startaddress(DllMain)
00090 #endif
00091 
00092 static void DrawInBuffer(long x, long y, fullscreenbuffer *Screen,
00093                          long X, long Y, long radius,
00094                          double r, double g, double b,
00095                          double z, float *Zb,
00096                          BOOL bDraw, long hide){
00097  /* mix in a white halo at the screen buffer location of the light source */
00098  long i,j;
00099  double d;
00100  fullscreenbuffer *S;
00101  /* bounding rectangle */
00102  for(i=x-radius;i<=x+radius;i++)for(j=y-radius;j<=y+radius;j++){
00103    if(i < 0 || i >= X || j < 0 || j >= Y)continue;
00104    S=(Screen + j*X + i);
00105    if(radius < 1)d=1.0;
00106    else{
00107      d=sqrt((double)(i-x)*(double)(i-x) + (double)(j-y)*(double)(j-y));
00108      d=255.0*((double)radius-d)/(double)radius;
00109      d=max(0.0,d);
00110    }
00111    /* mix to white */
00112    if(!hide || bDraw || z < *(Zb + j*X + i)){
00113      S->R = (unsigned char)min(255.0,(double)S->R+d*r);
00114      S->G = (unsigned char)min(255.0,(double)S->G+d*g);
00115      S->B = (unsigned char)min(255.0,(double)S->B+d*b);
00116    }
00117  }
00118  return;
00119 }
00120 
00121 long _RenderImageProcess(char *PrmList, XIMAGE *lpXimage){
00122  /* lights have been transformed to Renderer frame of reference */
00123  /* Z is UP, Y is forward (in front of observer, X to the RIGHT */
00124  /* the camera is located at 0,0,0. All real numbers are floats */
00125  /* xx and yy are screen co-ords of light (0,0) is at top left  */
00126  int i,j;
00127  char dummy[255];
00128  double x,y,z,mr,r,g,b;
00129  long xx,yy,radius,iradius,hide,miradius,type,id;
00130  float *Zb;
00131  BOOL  bDraw;
00132  if(lpXimage->Nlights == 0 || lpXimage->Lights == NULL)return 1;
00133  sscanf(PrmList,"%s %ld %ld %ld %ld %ld",dummy,&version,
00134         &iradius,&hide,&type,&id);
00135  if(lpXimage->Morph && lpXimage->mParameters != NULL){
00136    mr=lpXimage->MorphRatio;
00137    sscanf(lpXimage->mParameters,"%s %ld %ld",dummy,&version,&miradius);
00138    iradius=(long)((double)miradius + mr*((double)iradius-(double)miradius));
00139  }
00140  Zb=lpXimage->Zbuffer;
00141  for(i=0;i<lpXimage->Nlights;i++){
00142    if(type == 2 && lpXimage->Lights[i].type != DUMMYL)continue;
00143    if(type == 3 && lpXimage->Lights[i].AnimatorID != id)continue;
00144    x=lpXimage->Lights[i].p[0];
00145    y=lpXimage->Lights[i].p[1];
00146    z=lpXimage->Lights[i].p[2];
00147    if(y >= 1.000){                     /* all points in front of viewer */
00148      xx=lpXimage->Xmax/2 +
00149        (long)(lpXimage->Xscale*x/y);
00150      yy=lpXimage->Ymax/2 -
00151        (long)(lpXimage->Yscale*z/y);
00152      if(xx >= 0 && xx < lpXimage->Xmax &&
00153         yy >= 0 && yy < lpXimage->Ymax){
00154        /* this light is visible on screen                 */
00155        /* perspective transformation of light halo radius */
00156        if(Zb != NULL){      /* zbuffer       */
00157          if(y < *(Zb + (yy * lpXimage->Xmax) + xx))bDraw=TRUE;
00158          else bDraw=FALSE;  /* light obscured */
00159        }
00160        else bDraw=TRUE;
00161        radius = (long)(lpXimage->Xscale*(double)iradius/y);
00162        r=(double)(lpXimage->Lights[i].color[0])/255.0;
00163        g=(double)(lpXimage->Lights[i].color[1])/255.0;
00164        b=(double)(lpXimage->Lights[i].color[2])/255.0;
00165        DrawInBuffer(xx,yy,lpXimage->Screen,
00166                     lpXimage->Xmax,lpXimage->Ymax,radius,
00167                     r,g,b,
00168                     y,Zb,bDraw,hide);
00169      }
00170    }
00171  }
00172  return 1;
00173 }
00174 
00175 /*************** Function that renders anyof the OpenGL Functionality ************/
00176 
00177 long _RenderGLexternal(char *PrmList, XIMAGE *lpXimage){
00178 MessageBox(NULL,"Fog OpenGL function called","OK",MB_OK);
00179  return 1;
00180 }
00181 
00182 
00183 /*************** Functions used to set up      ***************/
00184 
00185 
00186 /* Dialog box callback  */
00187 BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam);
00188 
00189 static double rad=1.0;
00190 static long   hide=1,type=1,id = -1;
00191 static X__MEMORY_MANAGER *lpLocalEVI;
00192 
00193 char * _SetExternalParameters(
00194   char *Op,                 /* string for the parameters                  */
00195   HWND hWnd,                /* parent window                              */
00196   long ruler,               /* ruler scale value to facilitate scaling    */
00197   char *name,               /* name of DLL file with the effect           */
00198   X__MEMORY_MANAGER *lpEVI /* pointer to structure with memory functions */
00199                                     ){
00200  /* output name and buffer should be as long as necessary to hold full string */
00201  char buffer[256];
00202  long irad;       /* integer scaled radius value                */
00203  if(Op != NULL){  /* parameters exist so read them off the list */
00204    sscanf(Op,"%s %ld %ld %ld %ld %ld",buffer,&version,&irad,&hide,&type,&id);
00205    /* transform from World units to User units                  */
00206    rad=(double)irad/(double)ruler;
00207  }
00208  /*   Do the user interface as required to set up the effect, may use a */
00209  /*   dialog box etc. Return old string if cancelled (no change)        */
00210  lpLocalEVI=lpEVI;
00211  if(DialogBox(hDLLinstance,MAKEINTRESOURCE(DLG_HALO),hWnd,
00212               (DLGPROC)DlgProc) == FALSE)return Op;
00213  /* Free space occupied by old parameter string      */
00214  if(Op != NULL)CALL_FREE(Op);  /* free the old string */
00215  /* print the parameters into the buffer             */
00216  /* transform from User units to World units         */
00217  irad=(long)(rad*(double)ruler);
00218  sprintf(buffer,"%s %ld %ld %ld %ld %ld",name,version,irad,hide,type,id);
00219  /* Prepare the output buffer to take copy of parameter list */
00220  if((Op=(char *)CALL_MALLOC(strlen(buffer)+1)) == NULL){
00221   MessageBox (GetFocus(),"External effect: Out of memory","Error",
00222                 MB_OK|MB_TASKMODAL|MB_ICONSTOP);
00223    return NULL;
00224  }
00225  /* Copy the parameter string to the output buffer */
00226  strcpy(Op,buffer);
00227  return Op;
00228 }
00229 
00230 BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam){
00231  /* a radius value of 1.0 will give a halo of radius 1.0  unit     */
00232  /* for whatever co-ordinate system is in use for this animation   */
00233  /* the size relative to the actors can be determined by using the */
00234  /* co-ord dialog to check on the size of the actors               */
00235  char str[32];
00236  switch( msg ) {
00237    case WM_INITDIALOG:
00238      sprintf(str,"%.3f",rad);
00239      SetDlgItemText(hwnd,DLG_HALO_RADIUS,str);
00240      if(hide == 1)SendDlgItemMessage(hwnd,DLG_HALO_HIDE,BM_SETCHECK,TRUE,0);
00241      if(type == 1)SendDlgItemMessage(hwnd,DLG_HALO_TYPE1,BM_SETCHECK,TRUE,0);
00242      if(type == 2)SendDlgItemMessage(hwnd,DLG_HALO_TYPE2,BM_SETCHECK,TRUE,0);
00243      if(type == 3)SendDlgItemMessage(hwnd,DLG_HALO_TYPE3,BM_SETCHECK,TRUE,0);
00244      if(id >= 0)SendDlgItemMessage(hwnd,DLG_HALO_NAME,WM_SETTEXT,
00245                 0,(LPARAM)GetActorsName(lpLocalEVI->lpAni,id));
00246      CentreDialogOnScreen(hwnd);
00247      return TRUE;
00248    case WM_PAINT:
00249      PaintBackground(hwnd);
00250      break;
00251    case WM_COMMAND:
00252      switch(LOWORD(wparam)){
00253         case DLG_HALO_SETID:
00254           id=GetActorsID(lpLocalEVI->lpAni,hwnd);
00255           if(id >= 0)SendDlgItemMessage(hwnd,DLG_HALO_NAME,WM_SETTEXT,
00256                      0,(LPARAM)GetActorsName(lpLocalEVI->lpAni,id));
00257           break;
00258         case IDCANCEL:
00259           EndDialog(hwnd,FALSE);
00260           return(TRUE);
00261         case IDOK:
00262           if(GetDlgItemText(hwnd,DLG_HALO_RADIUS,str,12) != 0)
00263             sscanf(str,"%f",&rad);
00264           if(SendDlgItemMessage(hwnd,DLG_HALO_HIDE,BM_GETCHECK,0,0))
00265                hide=1;
00266           else hide=0;
00267           if(SendDlgItemMessage(hwnd,DLG_HALO_TYPE1,BM_GETCHECK,0,0))type=1;
00268           if(SendDlgItemMessage(hwnd,DLG_HALO_TYPE2,BM_GETCHECK,0,0))type=2;
00269           if(SendDlgItemMessage(hwnd,DLG_HALO_TYPE3,BM_GETCHECK,0,0))type=3;
00270           EndDialog(hwnd,TRUE);
00271           return(TRUE);
00272         default:
00273           break;
00274       }
00275       break;
00276     default: break;
00277  }
00278  return FALSE;
00279 }
00280 

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