GLOW.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 /* glow.c  image post-processor                                         */
00025 
00026 #include <stdlib.h>
00027 #include <stdio.h>
00028 #include <float.h>
00029 #include <math.h>
00030 #include <windows.h>
00031 #include "struct.h"           /* general structures    */
00032 #include "..\common\postprocess\ximage.h"
00033 #include "local.h"
00034 
00035 #include "glow.h"
00036 
00037 #if __X__MIPS__
00038 BOOL WINAPI _CRT_INIT(HINSTANCE ,DWORD , LPVOID );
00039 #endif
00040 
00041 static HINSTANCE hDLLinstance=NULL; /* use to pick up resources from DLL   */
00042 static long version=1;
00043 
00044 #include "utils.h"
00045 #include "paint.c"
00046 
00047 #if __WATCOMC__
00048 int APIENTRY LibMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00049 #elif __BC__
00050 BOOL WINAPI DllEntryPoint(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00051 #else
00052 BOOL WINAPI DllMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00053 #endif
00054   switch (dwReason) {
00055     case DLL_PROCESS_ATTACH:
00056 #if __X__MIPS__
00057       if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00058 #endif
00059       hDLLinstance = hDLL;  /* handle to DLL file */
00060       break;
00061     case DLL_PROCESS_DETACH:
00062 #if __X__MIPS__
00063       if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00064 #endif
00065       break;
00066   }
00067 return (int)TRUE;
00068 }
00069 
00070 #if __SC__
00071 #pragma startaddress(DllMain)
00072 #endif
00073 
00074 static void SetColour(unsigned char *colour, HWND parent){
00075  CHOOSECOLOR cc;
00076  static COLORREF CustColours[16]={
00077    RGB(255,255,255), RGB(239,239,239), RGB(223,223,223), RGB(207,207,207),
00078    RGB(191,191,191), RGB(175,175,175), RGB(159,159,159), RGB(143,143,143),
00079    RGB(127,127,127), RGB(111,111,111), RGB( 95, 95, 95), RGB( 79, 79, 79),
00080    RGB( 63, 63, 63), RGB( 47, 47, 47), RGB( 31, 31, 31), RGB( 15, 15, 15) };
00081  cc.lStructSize=sizeof(CHOOSECOLOR);
00082  cc.hwndOwner=parent;
00083  cc.rgbResult=RGB((BYTE)colour[0],(BYTE)colour[1],(BYTE)colour[2]);
00084  cc.lpCustColors=(LPDWORD)CustColours;
00085  cc.Flags= CC_RGBINIT;
00086  cc.lCustData=(DWORD)0;
00087  if(ChooseColor(&cc)){
00088    colour[0]=(unsigned char)GetRValue(cc.rgbResult);
00089    colour[1]=(unsigned char)GetGValue(cc.rgbResult);
00090    colour[2]=(unsigned char)GetBValue(cc.rgbResult);
00091  }
00092 }
00093 
00094 static BOOL Aboundary(long i, long j, long X, long Y, fullscreenbuffer *Si){
00095  fullscreenbuffer *S;
00096  if(i <= 0 || i >= X-1 || j <= 0 || j >= Y-1)return FALSE;
00097 // S=(Si + j*X + i - 1); if(S->A < 240)return TRUE;
00098 // S=(Si + j*X + i + 1); if(S->A < 240)return TRUE;
00099 // S=(Si + (j-1)*X + i); if(S->A < 240)return TRUE;
00100 // S=(Si + (j+1)*X + i); if(S->A < 240)return TRUE;
00101  S=(Si + j*X + i - 1); if(S->A < 128)return TRUE;
00102  S=(Si + j*X + i + 1); if(S->A < 128)return TRUE;
00103  S=(Si + (j-1)*X + i); if(S->A < 128)return TRUE;
00104  S=(Si + (j+1)*X + i); if(S->A < 128)return TRUE;
00105  return FALSE;
00106 }
00107 
00108 static void DrawAlphaBoundary(long x, long y, fullscreenbuffer *So,
00109                          long X, long Y, long radius,
00110                          fullscreenbuffer *Si,
00111                          long skip,
00112                          double I,double R, double G, double B){
00113  long i,j;
00114  double d;
00115  fullscreenbuffer *S;
00116  for(i=x-radius;i<=x+radius;i+=skip)for(j=y-radius;j<=y+radius;j+=skip){
00117    if(i < 0 || i >= X || j < 0 || j >= Y)continue;
00118    S=(Si + j*X + i);
00119 //   if(S->A > 240)continue;
00120    if(S->A > 127)continue;
00121    if(radius < 1)d=0.5;
00122    else{
00123      d=sqrt((double)(i-x)*(double)(i-x) + (double)(j-y)*(double)(j-y));
00124      if(d > (double)radius)continue;
00125      d=1.0 - d/(double)radius;
00126    }
00127    d=I*d;
00128    S=(So + j*X + i);
00129    S->R = (unsigned char)min(255.0,(double)S->R+R*d);
00130    S->G = (unsigned char)min(255.0,(double)S->G+G*d);
00131    S->B = (unsigned char)min(255.0,(double)S->B+B*d);
00132  }
00133  return;
00134 }
00135 
00136 static BOOL boundary(long i, long j, long X, long Y,
00137                      fullscreenbuffer *Si, long c1, long c2, long c3){
00138  fullscreenbuffer *S;
00139  if(i <= 0 || i >= X-1 || j <= 0 || j >= Y-1)return FALSE;
00140  S=(Si + j*X + i - 1);
00141  if(S->R != c1 || S->G != c2 || S->B != c3)return TRUE;
00142  S=(Si + j*X + i + 1);
00143  if(S->R != c1 || S->G != c2 || S->B != c3)return TRUE;
00144  S=(Si + (j-1)*X + i);
00145  if(S->R != c1 || S->G != c2 || S->B != c3)return TRUE;
00146  S=(Si + (j+1)*X + i);
00147  if(S->R != c1 || S->G != c2 || S->B != c3)return TRUE;
00148  return FALSE;
00149 }
00150 
00151 static void DrawInBuffer(long x, long y, fullscreenbuffer *So,
00152                          long X, long Y, long radius,
00153                          fullscreenbuffer *Si, BOOL exclude,
00154                          long c1, long c2, long c3,
00155                          long skip,
00156                          double z, float *Zb, double I,
00157                          double R, double G, double B){
00158  long i,j;
00159  double d;
00160  fullscreenbuffer *S;
00161  for(i=x-radius;i<=x+radius;i+=skip)for(j=y-radius;j<=y+radius;j+=skip){
00162    if(i < 0 || i >= X || j < 0 || j >= Y)continue;
00163    S=(Si + j*X + i);
00164    if(S->R == c1 && S->G == c2 && S->B == c3){
00165      if(exclude)continue;
00166    }
00167    else if(z > *(Zb + j*X + i))continue;
00168    if(radius < 1)d=0.5;
00169    else{
00170      d=sqrt((double)(i-x)*(double)(i-x) + (double)(j-y)*(double)(j-y));
00171      if(d > (double)radius)continue;
00172      d=1.0 - d/(double)radius;
00173    }
00174    d=I*d;
00175    S=(So + j*X + i);
00176    /* mix to colour */
00177    S->R = (unsigned char)min(255.0,(double)S->R+R*d);
00178    S->G = (unsigned char)min(255.0,(double)S->G+G*d);
00179    S->B = (unsigned char)min(255.0,(double)S->B+B*d);
00180  }
00181  return;
00182 }
00183 
00184 long _RenderImageProcess(char *PrmList, XIMAGE *lpXimage){
00185  long i,j;
00186  char dummy[255];
00187  double z,scale,I,mr,fade;
00188  long radius,iradius,hot,c1,c2,c3,Xmax,Ymax,ifade;
00189  long miradius,mhot,mc1,mc2,mc3,mifade;
00190  float *Zb;
00191  fullscreenbuffer *S,*Screen,*So,*Si;
00192  BOOL  bDraw=TRUE,bMorph=FALSE;
00193  sscanf(PrmList,"%s %ld %ld %ld %ld %ld %ld %ld",dummy,&version,&c1,&c2,&c3,
00194         &iradius,&hot,&ifade);
00195  if(lpXimage->Morph && lpXimage->mParameters != NULL){
00196    bMorph=TRUE; mr=lpXimage->MorphRatio;
00197    sscanf(lpXimage->mParameters,"%s %ld %ld %ld %ld %ld %ld %ld",dummy,
00198           &version,&mc1,&mc2,&mc3,&miradius,&mhot,&mifade);
00199  }
00200  if((Zb=lpXimage->Zbuffer) == NULL)return 0;
00201  Xmax=lpXimage->Xmax; Ymax=lpXimage->Ymax;
00202  if(bMorph){
00203   fade=((double)mifade + mr*((double)ifade-(double)mifade))/100.0;
00204  }
00205  else fade=(double)ifade/100.0;
00206  scale=Xmax/320.0*fade;
00207  Screen=lpXimage->Screen;
00208  So=(fullscreenbuffer *)X__Malloc(Xmax*Ymax*(long)sizeof(fullscreenbuffer));
00209  if(So == NULL){
00210    MessageBox(GetFocus(),"Memory Out",NULL,MB_OK);
00211    return 0;
00212  }
00213  memcpy(So,Screen,sizeof(fullscreenbuffer)*Xmax*Ymax);
00214  if(hot < 4){
00215    for(j=0;j<Ymax;j++)for(i=0;i<Xmax;i++){
00216      S=(Screen + j*Xmax + i);
00217      z = *(Zb + j*Xmax + i);
00218      if(z > FARAWAY - 10.0)continue;
00219      if(S->R != c1 || S->G != c2 || S->B != c3)continue;
00220      S=(So + j*Xmax + i);
00221      if(hot == 1){
00222        S->R = S->G = S->B = 250; // hot
00223        if(boundary(i,j,Xmax,Ymax,Screen,c1,c2,c3)){
00224          radius=13.0*scale;
00225          DrawInBuffer(i,j,So,Xmax,Ymax,radius,Screen,TRUE,c1,c2,c3,
00226                       1,
00227                       z,Zb,
00228                       0.1,
00229                       255.0,0.0,0.0);
00230          radius=8.0*scale;
00231          DrawInBuffer(i,j,So,Xmax,Ymax,radius,Screen,TRUE,c1,c2,c3,
00232                       1,
00233                       z,Zb,
00234                       0.1,
00235                       0.0,255.0,0.0);
00236          radius=2.0*scale;
00237          DrawInBuffer(i,j,So,Xmax,Ymax,radius,Screen,TRUE,c1,c2,c3,
00238                       1,
00239                       z,Zb,
00240                       0.1,
00241                       255.0,255.0,255.0);
00242        }
00243      }
00244      else if(hot == 2){
00245        S->R = S->G = 250; S->B= 128; // warm
00246        if(boundary(i,j,Xmax,Ymax,Screen,c1,c2,c3)){
00247          radius=13.0*scale;  // 10
00248          DrawInBuffer(i,j,So,Xmax,Ymax,radius,Screen,FALSE,c1,c2,c3,
00249                       1,
00250                       z,Zb,
00251                       0.1,
00252                       255.0,0.0,0.0);
00253          radius=4.0*scale;
00254          DrawInBuffer(i,j,So,Xmax,Ymax,radius,Screen,FALSE,c1,c2,c3,
00255                       1,
00256                       z,Zb,
00257                       0.1,
00258                       255.0,255.0,255.0);
00259        }
00260      }
00261      else{
00262        S->R = S->G = 188; S->B = 240;  // cool
00263        if(boundary(i,j,Xmax,Ymax,Screen,c1,c2,c3)){
00264          radius=20.0*scale;
00265          DrawInBuffer(i,j,So,Xmax,Ymax,radius,Screen,FALSE,c1,c2,c3,
00266                       1,
00267                       z,Zb,
00268                       0.1,
00269                       48.0,48.0,255.0);
00270          radius=8.0*scale;
00271          DrawInBuffer(i,j,So,Xmax,Ymax,radius,Screen,FALSE,c1,c2,c3,
00272                       1,
00273                       z,Zb,
00274                       0.25,
00275                       90.0,90.0,255.0);
00276        }
00277      }
00278    }
00279  }
00280  else{
00281    if(bMorph){
00282      I=((double)miradius + mr*((double)iradius-(double)miradius))/100.0;
00283    }
00284    else I=(double)iradius/100.0;  // radiate
00285    for(j=0;j<Ymax;j++)for(i=0;i<Xmax;i++){
00286      Si=(Screen + j*Xmax + i);
00287      if(Si->A < 64)continue;
00288      S=(So + j*Xmax + i);
00289      if(Aboundary(i,j,Xmax,Ymax,Screen)){
00290        radius=13.0*scale;  // 10
00291        DrawAlphaBoundary(i,j,So,Xmax,Ymax,radius,Screen,1,
00292                     0.1,
00293                     255.0,0.0,0.0);
00294        radius=8.0*scale;
00295        DrawAlphaBoundary(i,j,So,Xmax,Ymax,radius,Screen,1,
00296                     0.1,
00297                     255.0,255.0,0.0);
00298      }
00299 //     if(Si->A >= 64){
00300      if(Si->A > 128){
00301        S->R = (unsigned char)min(255.0,(1.0-I)*(double)Si->R+255.0*I);
00302        S->G = (unsigned char)min(255.0,(1.0-I)*(double)Si->G+220.0*I);
00303        S->B = (unsigned char)min(255.0,(1.0-I)*(double)Si->B+0.0*I);
00304      }
00305    }
00306  }
00307  memcpy(Screen,So,sizeof(fullscreenbuffer)*Xmax*Ymax);
00308  X__Free(So);
00309  return 1;
00310 }
00311 
00312 /*************** Function that renders anyof the OpenGL Functionality ************/
00313 
00314 long _RenderGLexternal(char *PrmList, XIMAGE *lpXimage){
00315 MessageBox(NULL,"Fog OpenGL function called","OK",MB_OK);
00316  return 1;
00317 }
00318 
00319 
00320 BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam);
00321 
00322 static long   irad=0,hot=1,c1=0,c2=255,c3=0,fade=100;
00323 
00324 char * _SetExternalParameters(
00325   char *Op,                 /* string for the parameters                  */
00326   HWND hWnd,                /* parent window                              */
00327   long ruler,               /* ruler scale value to facilitate scaling    */
00328   char *name,               /* name of DLL file with the effect           */
00329   X__MEMORY_MANAGER *lpEVI /* pointer to structure with memory functions */
00330                                     ){
00331  char buffer[256];
00332  if(Op != NULL){  /* parameters exist so read them off the list */
00333    sscanf(Op,"%s %ld %ld %ld %ld %ld %ld %ld",buffer,&version,&c1,&c2,&c3,
00334           &irad,&hot,&fade);
00335  }
00336  if(DialogBox(hDLLinstance,MAKEINTRESOURCE(DLG_GLOW),hWnd,
00337               (DLGPROC)DlgProc) == FALSE)return Op;
00338  if(Op != NULL)CALL_FREE(Op);  /* free the old string */
00339  sprintf(buffer,"%s %ld %ld %ld %ld %ld %ld %ld",name,version,c1,c2,c3,
00340          irad,hot,fade);
00341  if((Op=(char *)CALL_MALLOC(strlen(buffer)+1)) == NULL){
00342   MessageBox (GetFocus(),"External effect: Out of memory","Error",
00343                 MB_OK|MB_TASKMODAL|MB_ICONSTOP);
00344    return NULL;
00345  }
00346  strcpy(Op,buffer);
00347  return Op;
00348 }
00349 
00350 BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam){
00351  BOOL err;
00352  char str[32];
00353  switch( msg ) {
00354    case WM_INITDIALOG:
00355      SetDlgItemInt(hwnd,DLG_GLOW_RADIUS,irad,FALSE);
00356      SetDlgItemInt(hwnd,DLG_GLOW_FADE,fade,FALSE);
00357      if     (hot == 1)
00358        SendDlgItemMessage(hwnd,DLG_GLOW_HOT,BM_SETCHECK,TRUE,0);
00359      if     (hot == 2)
00360        SendDlgItemMessage(hwnd,DLG_GLOW_WARM,BM_SETCHECK,TRUE,0);
00361      if     (hot == 3)
00362        SendDlgItemMessage(hwnd,DLG_GLOW_COOL,BM_SETCHECK,TRUE,0);
00363      if     (hot == 4)
00364        SendDlgItemMessage(hwnd,DLG_GLOW_RADIATE,BM_SETCHECK,TRUE,0);
00365      CentreDialogOnScreen(hwnd);
00366      return TRUE;
00367    case WM_PAINT:
00368      PaintBackground(hwnd);
00369      break;
00370    case WM_DRAWITEM:{
00371        LPDRAWITEMSTRUCT lpdis;
00372        HBRUSH   hbr,hbrold;
00373        BYTE r,g,b;
00374        lpdis=(LPDRAWITEMSTRUCT)lparam;
00375        if(lpdis->CtlID == DLG_GLOW_COLOUR){
00376          r=(BYTE)c1; g=(BYTE)c2; b=(BYTE)c3;
00377          if(lpdis->itemState & ODS_SELECTED)
00378             InvertRect(lpdis->hDC,&(lpdis->rcItem));
00379          else{
00380            hbr=CreateSolidBrush(RGB(r,g,b));
00381            hbrold=SelectObject(lpdis->hDC,hbr);
00382            Rectangle(lpdis->hDC,lpdis->rcItem.left,lpdis->rcItem.top,
00383                          lpdis->rcItem.right,lpdis->rcItem.bottom);
00384            SelectObject(lpdis->hDC,hbrold);
00385            DeleteObject(hbr);
00386          }
00387        }
00388      }
00389      break;
00390    case WM_COMMAND:
00391      switch(LOWORD(wparam)){
00392         case DLG_GLOW_COLOUR:{
00393             unsigned char colour[3];
00394             SetColour(colour,hwnd);
00395             c1=(long)colour[0]; c2=(long)colour[1]; c3=(long)colour[2];
00396             InvalidateRect(GetDlgItem(hwnd,DLG_GLOW_COLOUR),NULL,FALSE);
00397           }
00398           break;
00399         case IDCANCEL:
00400           EndDialog(hwnd,FALSE);
00401           return(TRUE);
00402         case IDOK:
00403           if     (SendDlgItemMessage(hwnd,DLG_GLOW_RADIATE,BM_GETCHECK,0,0))
00404             hot=4;
00405           else if(SendDlgItemMessage(hwnd,DLG_GLOW_COOL,BM_GETCHECK,0,0))
00406             hot=3;
00407           else if(SendDlgItemMessage(hwnd,DLG_GLOW_WARM,BM_GETCHECK,0,0))
00408             hot=2;
00409           else
00410             hot=1;
00411           irad=GetDlgItemInt(hwnd,DLG_GLOW_RADIUS,&err,FALSE);
00412           if(irad < 0)irad=0;
00413           if(irad > 100)irad=100;
00414           fade=GetDlgItemInt(hwnd,DLG_GLOW_FADE,&err,FALSE);
00415           if(irad < 0)irad=0;
00416           EndDialog(hwnd,TRUE);
00417           return(TRUE);
00418         default:
00419           break;
00420       }
00421       break;
00422     default: break;
00423  }
00424  return FALSE;
00425 }
00426 

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