MYSTARS.C

Go to the documentation of this file.
00001 /* --
00002 OpenFX version 1.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 /* STARS.C  example image post-processing external DLL for            */
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 "stars.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 
00043 /************************** Local Utility Functions ***********************/
00044 
00045 #include "utils.h"
00046 
00047 /************************** DLL entry point ********************************/
00048 
00049 int APIENTRY LibMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00050   switch (dwReason) {
00051     case DLL_PROCESS_ATTACH:
00052 #if __X__MIPS__
00053       if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00054 #endif
00055       hDLLinstance = hDLL;  /* handle to DLL file */
00056       break;
00057     case DLL_PROCESS_DETACH:
00058 #if __X__MIPS__
00059       if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00060 #endif
00061       break;
00062   }
00063 return (int)TRUE;
00064 }
00065 
00066 #if __SC__
00067 #pragma startaddress(LibMain)
00068 #endif
00069 
00070 /*******************************************************************\
00071 |                Code that executes the process                     |
00072 \*******************************************************************/
00073 
00074 static void DrawPointInBuffer(long x, long y,
00075                               fullscreenbuffer *Screen,
00076                               long X, long Y){
00077  fullscreenbuffer *S;
00078  S=(Screen + y*X + x);
00079  /* if not black don't draw, this is like 'blue screen' and should */
00080  /* simulate drawing in background only (well quite near!)         */
00081  if(S->R > 1 || S->G > 1 || S->B > 1)return;
00082  S->R = (unsigned char)255.0;
00083  S->G = (unsigned char)255.0;
00084  S->B = (unsigned char)255.0;
00085  return;
00086 }
00087 
00088 void DrawInBuffer(fullscreenbuffer *Screen, int Xmax, int Ymax,
00089                   int x, int y, unsigned char v ){
00090  int r,g,b;
00091  fullscreenbuffer *S;
00092  if(x < 0 || y < 0 || x >= Xmax || y >= Ymax)return;
00093  S=(Screen+y*Xmax+x);
00094  if(S->R > 1 || S->G > 1 || S->B > 1)return;
00095  r=(int)S->R+(int)v;
00096  g=(int)S->G+(int)v;
00097  b=(int)S->B+(int)v;
00098  S->R=(r>255) ? 255:r;
00099  S->G=(g>255) ? 255:g;
00100  S->B=(b>255) ? 255:b;
00101 }
00102 
00103 #define frac(z) fmod(z,1.0)
00104 
00105 void DrawAApixel(double x, double y, double w, double h,int brite,
00106                  fullscreenbuffer *S, int X, int Y){
00107   int xa,xb,ya,yb,i,j;
00108   double x2,y2,lfrac,rfrac,tfrac,bfrac,xfrac,yfrac;
00109   x2 = x + w;
00110   y2 = y + w;
00111   xa = (int)x;
00112   xb = (int)x2;
00113   ya = (int)y;
00114   yb = (int)y2;
00115   lfrac = 1.0-frac(x);
00116   rfrac = frac(x2);
00117   tfrac = 1.0-frac(y);
00118   bfrac = frac(y2);
00119   if (xa==xb) {
00120     xfrac = lfrac+rfrac-1.0;
00121     if (ya==yb) {
00122       DrawInBuffer(S,X,Y,xa,ya,xfrac*(tfrac+bfrac-1.0)*brite);
00123     }
00124     else {
00125       DrawInBuffer(S,X,Y,xa,ya,xfrac*tfrac*brite);
00126       for (j=ya+1; j<yb; j++) DrawInBuffer(S,X,Y,xa,j,xfrac*brite);
00127       DrawInBuffer(S,X,Y,xa,yb,xfrac*bfrac*brite);
00128     }
00129   }
00130   else {
00131     if (ya==yb) {
00132       yfrac = tfrac+bfrac-1.0;
00133       DrawInBuffer(S,X,Y,xa,ya,yfrac*lfrac*brite);
00134       for (i=xa+1; i<xb; i++) DrawInBuffer(S,X,Y,i,ya,yfrac*brite);
00135       DrawInBuffer(S,X,Y,xb,ya,yfrac*rfrac*brite);
00136     }
00137     else {
00138       DrawInBuffer(S,X,Y,xa,ya,tfrac*lfrac*brite);
00139       for (i=xa+1; i<xb; i++) DrawInBuffer(S,X,Y,i,ya,tfrac*brite);
00140       DrawInBuffer(S,X,Y,xb,ya,tfrac*rfrac*brite);
00141       for (j=ya+1; j<yb; j++) {
00142         DrawInBuffer(S,X,Y,xa,j,lfrac*brite);
00143         for (i=xa+1; i<xb; i++)DrawInBuffer(S,X,Y,i,j,brite);
00144         DrawInBuffer(S,X,Y,xb,j,rfrac*brite);
00145       }
00146       DrawInBuffer(S,X,Y,xa,yb,bfrac*lfrac*brite);
00147       for (i=xa+1; i<xb; i++) DrawInBuffer(S,X,Y,i,yb,bfrac*brite);
00148       DrawInBuffer(S,X,Y,xb,yb,bfrac*rfrac*brite);
00149     }
00150   }
00151 }
00152 
00153 long RegularGridOfStars(char *PrmList, XIMAGE *lpXimage){
00154  /* lights have been transformed to Renderer frame of reference */
00155  /* Z is UP, Y is forward (in front of observer, X to the RIGHT */
00156  /* the camera is located at 0,0,0. All real numbers are floats */
00157  /* xx and yy are screen co-ords of light (0,0) is at top left  */
00158  long i,j,k,ispacing,nside;
00159  char dummy[255];
00160  double x,y,z,xp,yp,zp;
00161  double xx,yy;      /* screen coordinates of point to be plotted  */
00162  sscanf(PrmList,"%s %ld %ld %ld",dummy,&i,&nside,&ispacing);
00163  for(i=0;i<nside;i++){
00164    xp=(i-nside/2)*ispacing;
00165  for(j=0;j<nside;j++){
00166    yp=(j-nside/2)*ispacing;
00167  for(k=0;k<nside;k++){
00168    zp=(k-nside/2)*ispacing;
00169    TransformIntoView(lpXimage->ViewTransform,xp,yp,zp,&x,&y,&z);
00170    if(y >= 1.000){  /* all points in front of viewer */
00171      xx=(double)lpXimage->Xmax/2.0 + (lpXimage->Xscale*x/y);
00172      yy=(double)lpXimage->Ymax/2.0 - (lpXimage->Yscale*z/y);
00173      if((long)xx >= 0 && (long)xx < lpXimage->Xmax &&
00174         (long)yy >= 0 && (long)yy < lpXimage->Ymax){
00175        /* this point is visible on screen */
00176 //       DrawPointInBuffer((long)xx,(long)yy,lpXimage->Screen,
00177 //                        lpXimage->Xmax,lpXimage->Ymax);
00178        DrawAApixel(xx,yy,1.5,1.5,255,lpXimage->Screen,
00179                         lpXimage->Xmax,lpXimage->Ymax);
00180      }
00181    }
00182  }
00183  }
00184  }
00185  return 1;
00186 }
00187 
00188 PSTR FileInPath(PSTR pstrPath){
00189  PSTR pstr;
00190  pstr = pstrPath + strlen(pstrPath);
00191  while (pstr > pstrPath) {
00192      pstr = (AnsiPrev(pstrPath, pstr));
00193      if (*pstr == '\\' || *pstr == ':' || *pstr == '/') {
00194          pstr = (AnsiNext(pstr));
00195          break;
00196      }
00197  }
00198  return pstr;
00199 }
00200 
00201 typedef struct{
00202  float x,y,z,fmag;
00203  unsigned char mag;
00204 } Star;
00205 
00206 long CALLBACK RenderImageProcess(char *PrmList, XIMAGE *lpXimage){
00207  BOOL logarithmic=FALSE;
00208  int ix,starcount,mag,bright,dim;
00209  float factor2;
00210  Star *stardata=NULL;
00211  FILE *istream=NULL;
00212  long i,j,k,ispacing,nside;
00213  char dummy[255],starname[16];
00214  double x,y,z,xp,yp,zp;
00215  double xx,yy;      /* screen coordinates of point to be plotted  */
00216  sscanf(PrmList,"%s %ld",dummy,&i);
00217  if(i == 0){
00218    RegularGridOfStars(PrmList,lpXimage);
00219    return 1;
00220  }
00221  sscanf(PrmList,"%s %ld %ld %ld %s",dummy,&i,&j,&k,starname);
00222  *FileInPath(dummy) = '\0';
00223  strcat(dummy,starname);
00224  if((istream=fopen(dummy,"rb"))== NULL){
00225    MessageBeep(MB_OK);
00226    return 0;
00227  }
00228  if(fread(&starcount,sizeof(int),1,istream)!=1)goto CLOSEDOWN;
00229  if(starcount < 1)goto CLOSEDOWN;
00230  if((stardata=X__Malloc(starcount*sizeof(Star)))==NULL){
00231    MessageBeep(MB_OK);
00232    goto CLOSEDOWN;
00233  }
00234  if(fread(stardata,sizeof(Star),starcount,istream)!=starcount){
00235    MessageBeep(MB_OK);
00236    goto CLOSEDOWN;
00237  }
00238  fclose(istream); istream=NULL;
00239  bright=255; dim=128;
00240  factor2=((float)bright-(float)dim)/10.0;
00241  for(ix=0; ix<starcount; ++ix){
00242    mag=stardata[ix].fmag;
00243    if(logarithmic)stardata[ix].mag=(int)(pow(10.0-mag,2.407));
00244    else           stardata[ix].mag=(int)((10.0-mag)*factor2)+dim;
00245  }
00246  for(i=0;i<starcount;i++){
00247    xp=stardata[i].x*65536.0;
00248    yp=stardata[i].y*65536.0;
00249    zp=stardata[i].z*65536.0;
00250    TransformIntoView(lpXimage->ViewTransform,xp,yp,zp,&x,&y,&z);
00251    if(y >= 1.000){  /* all points in front of viewer */
00252      xx=(double)lpXimage->Xmax/2.0 + (lpXimage->Xscale*x/y);
00253      yy=(double)lpXimage->Ymax/2.0 - (lpXimage->Yscale*z/y);
00254      if((long)xx >= 0 && (long)xx < lpXimage->Xmax &&
00255         (long)yy >= 0 && (long)yy < lpXimage->Ymax){
00256        /* this point is visible on screen */
00257        DrawAApixel(xx,yy,1.5,1.5,stardata[i].mag,lpXimage->Screen,
00258                         lpXimage->Xmax,lpXimage->Ymax);
00259      }
00260    }
00261  }
00262  CLOSEDOWN:
00263  if(stardata != NULL)X__Free(stardata);
00264  if(istream != NULL)fclose(istream);
00265  return 1;
00266 }
00267 
00268 /*************** Functions used to set up      ***************/
00269 
00270 
00271 /* Dialog box callback  */
00272 BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam);
00273 
00274 /* static variables     */
00275 static double spacing=1.0;
00276 static long startype=0,nside=10;
00277 static char starfile[16]="EARTH.STB";
00278 
00279 /* Function called      */
00280 char *CALLBACK SetExternalParameters(
00281   char *Op,                 /* string for the parameters                  */
00282   HWND hWnd,                /* parent window                              */
00283   long ruler,               /* ruler scale value to facilitate scaling    */
00284   char *name,               /* name of DLL file with the effect           */
00285   X__MEMORY_MANAGER *lpEVI /* pointer to structure with memory functions */
00286                                     ){
00287  /* output name and buffer should be as long as necessary to hold full string */
00288  char buffer[256];
00289  int ispacing;
00290  if(Op != NULL){  /* parameters exist so read them off the list */
00291    sscanf(Op,"%s %ld %ld %ld %s",buffer,&startype,&nside,&ispacing,starfile);
00292    spacing=(double)ispacing/(double)ruler;
00293  }
00294  /*   Do the user interface as required to set up the effect, may use a     */
00295  /*   dialog box etc. Return old string if effect is cancelled (no change)  */
00296  if(DialogBox(hDLLinstance,MAKEINTRESOURCE(DLG_STARS),hWnd,
00297               (DLGPROC)DlgProc) == FALSE)return Op;
00298  /* Free space occupied by old parameter string */
00299  if(Op != NULL)CALL_FREE(Op);  /* free the old string */
00300  /* print the parameters into the buffer */
00301  ispacing=(long)(spacing*(double)ruler);
00302  sprintf(buffer,"%s %ld %ld %ld %s",name,startype,nside,ispacing,starfile);
00303  /* Prepare the output buffer to take copy of parameter list */
00304  if((Op=(char *)CALL_MALLOC(strlen(buffer)+1)) == NULL){
00305   MessageBox (GetFocus(),"External effect: Out of memory","Error",
00306                 MB_OK|MB_TASKMODAL|MB_ICONSTOP);
00307    return NULL;
00308  }
00309  /* Copy the parameter string to the output buffer */
00310  strcpy(Op,buffer);
00311  return Op;
00312 }
00313 
00314 BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam){
00315  char temp[16];
00316  BOOL err;
00317  switch( msg ) {
00318    case WM_INITDIALOG:
00319      if(startype == 0)
00320        SendDlgItemMessage(hwnd,DLG_STARS_REGULAR,BM_SETCHECK,TRUE,0);
00321      else
00322        SendDlgItemMessage(hwnd,DLG_STARS_FILE,BM_SETCHECK,TRUE,0);
00323      SetDlgItemText(hwnd,DLG_STARS_NAME,starfile);
00324      SetDlgItemInt(hwnd,DLG_STARS_NSIDE,nside,FALSE);
00325      sprintf(temp,"%.2f",spacing);
00326      SetDlgItemText(hwnd,DLG_STARS_SPACING,temp);
00327      CentreDialogOnScreen(hwnd);
00328      return TRUE;
00329    case WM_COMMAND:
00330      switch(LOWORD(wparam)){
00331         case IDCANCEL:
00332           EndDialog(hwnd,FALSE);
00333           return(TRUE);
00334         case IDOK:
00335           if(SendDlgItemMessage(hwnd,DLG_STARS_FILE,BM_GETCHECK,0,0))
00336                startype=1;
00337           else startype=0;
00338           if(GetDlgItemText(hwnd,DLG_STARS_NAME,starfile,12) == 0)
00339             strcpy(starfile,"EARTH.STB");
00340           if(GetDlgItemText(hwnd,DLG_STARS_SPACING,temp,12) == 0)
00341             spacing=1.0;
00342           else spacing=atof(temp);
00343           nside=GetDlgItemInt(hwnd,DLG_STARS_NSIDE,&err,FALSE);
00344           if(nside < 2)nside=2;
00345           EndDialog(hwnd,TRUE);
00346           return(TRUE);
00347         default:
00348           break;
00349       }
00350       break;
00351     default: break;
00352  }
00353  return FALSE;
00354 }
00355 

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