reptile.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 //    reptile
00025 
00026 #include <stdlib.h>
00027 #include <stdio.h>
00028 #include <math.h>
00029 #include <float.h>
00030 #include <windows.h>
00031 #include <gl/gl.h>
00032 
00033 #if __ZTC__ || __SC__
00034 #ifndef max
00035 #define max(a,b)  ( ((a) > (b)) ? (a) : (b) )
00036 #endif
00037 #endif
00038 
00039 #if __WATCOMC__
00040 #define PI 3.1415926
00041 #endif
00042 
00043 #if __X__MIPS__
00044 BOOL WINAPI _CRT_INIT(HINSTANCE ,DWORD , LPVOID );
00045 #endif
00046 
00047 static HINSTANCE hDLLinstance=NULL;
00048 
00049 #include "..\animate\memory.h" /* for memory definition */
00050 #include "..\animate\memdef.h" /* local names           */
00051 #include "defines.h"
00052 #include "rstruct.h"
00053 #include "reptile.h"
00054 
00055 
00056 #if __WATCOMC__
00057 int APIENTRY LibMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00058 #else
00059 BOOL WINAPI DllMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00060 #endif
00061   HANDLE ghMod;
00062   switch (dwReason) {
00063     case DLL_PROCESS_ATTACH:
00064 #if __X__MIPS__
00065       if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00066 #endif
00067       hDLLinstance = hDLL;  /* handle to DLL file */
00068       break;
00069     case DLL_PROCESS_DETACH:
00070 #if __X__MIPS__
00071       if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00072 #endif
00073       break;
00074   }
00075   return (int)TRUE;
00076 }
00077 
00078 #if __SC__
00079 #pragma startaddress(DllMain)
00080 #endif
00081 
00082 #define VECCOPY(a,b)    { b[0] = a[0]; b[1] = a[1]; b[2] = a[2]; }
00083 #define VECSUM(a,b,c)   { c[0]=a[0]+b[0]; c[1]=a[1]+b[1]; c[2]=a[2]+b[2];}
00084 #define VECSUB(a,b,c)   { c[0]=a[0]-b[0]; c[1]=a[1]-b[1]; c[2]=a[2]-b[2];}
00085 #define VECSCALE(a,b,c) { c[0]=(a)*b[0]; c[1]=(a)*b[1]; c[2]=(a)*b[2];}
00086 #define DOT(a,b)        ( (a[0]*b[0]) + (a[1]*b[1]) + (a[2]*b[2]) )
00087 #define CROSS(v1,v2,r)  { \
00088                           r[0] = (v1[1]*v2[2]) - (v2[1]*v1[2]);  \
00089                           r[1] = (v1[2]*v2[0]) - (v1[0]*v2[2]);  \
00090                           r[2] = (v1[0]*v2[1]) - (v2[0]*v1[1]);  \
00091                         }
00092 
00093 #define IMOD(z,a) ((z) - ((z)/(a))*(a))
00094 
00095 #define PATTERN(x,y,z)   ( ((z)+16384L)*64536L +  \
00096                            ((y)+16384L)*32768L +  \
00097                            ((x)+16384L))
00098 #define FLOOR(x) ((x) >= 0.0 ? floor(x) : (0.0 - floor(0.0 - (x)) - 1.0))
00099 #define FMOD(x,a) ((x) >= 0.0 ? fmod(x,a) :(a - fmod(-(x),a)))
00100 #define ROOT32 0.866025403
00101 #define ROOT3   1.73205080
00102 
00103 
00104 static void mix(double *r, double *g, double *b, double mx,
00105                 double r1, double g1, double b1,
00106                 double r2, double g2, double b2){
00107  *r = mx*r1 + (1.0-mx)*r2;
00108  *g = mx*g1 + (1.0-mx)*g2;
00109  *b = mx*b1 + (1.0-mx)*b2;
00110 }
00111 
00112 static double size=0.4,edge=0.8;
00113 static double c1[3]={255.0,0.0,0.0};
00114 static double c2[3]={255.0,255.0,0.0};
00115 static double c3[3]={0.0,0.0,255.0};
00116 static double x=1.0,y=1.0,z=1.0;
00117 
00118 #if 0
00119 long CALLBACK ExternalTextureStartup(
00120 #else
00121 long _ExternalTextureStartup(
00122 #endif
00123   long frame,long nframes,char *parameter_list, X__SHADER *lpEVI){
00124  if(parameter_list[0] != '#'){
00125    MessageBox ( GetFocus(),
00126                 (LPCTSTR) "External texture: Startup",
00127                 (LPCTSTR) "Parameter list missing",
00128                 MB_OK | MB_SYSTEMMODAL );
00129  }
00130  else {
00131   parameter_list++;
00132   sscanf(parameter_list,"%f %f %f  %f %f  %f %f %f  %f %f %f   %f %f %f",
00133          &x,&y,&z,&size,&edge,
00134          &c1[0],&c1[1],&c1[2],
00135          &c2[0],&c2[1],&c2[2],
00136          &c3[0],&c3[1],&c3[2]);
00137  }
00138  return LoadAndCompileShader("reptile");
00139 }
00140 
00141 #if 0
00142 long CALLBACK ExternalTextureMorph(
00143 #else
00144 long _ExternalTextureMorph(
00145 #endif
00146  char *parameter_list, double mr){
00147  int i;
00148  double size_m,edge_m;
00149  double c1_m[3],c2_m[3],c3_m[3];
00150  double x_m,y_m,z_m;
00151  parameter_list++;
00152  sscanf(parameter_list,"%f %f %f  %f %f  %f %f %f  %f %f %f   %f %f %f",
00153         &x_m,&y_m,&z_m,&size_m,&edge_m,
00154         &c1_m[0],&c1_m[1],&c1_m[2],
00155         &c2_m[0],&c2_m[1],&c2_m[2],
00156         &c3_m[0],&c3_m[1],&c3_m[2]);
00157  for(i=0;i<3;i++)c1[i]=c1_m[i]+(c1[i]-c1_m[i])*mr;
00158  for(i=0;i<3;i++)c2[i]=c2_m[i]+(c2[i]-c2_m[i])*mr;
00159  for(i=0;i<3;i++)c3[i]=c3_m[i]+(c3[i]-c3_m[i])*mr;
00160  size=size_m+(size-size_m)*mr;
00161  edge=edge_m+(edge-edge_m)*mr;
00162  x=x_m+(x-x_m)*mr;
00163  y=y_m+(y-y_m)*mr;
00164  z=z_m+(z-z_m)*mr;
00165  return 1;
00166 }
00167 
00168 #if 0
00169 long CALLBACK ExternalTextureProcedure(
00170 #else
00171 long _ExternalTextureProcedure(
00172 #endif
00173   long coord_type,  vector p, vector n,
00174   double alpha, double beta, double gamma,
00175   double bump,  double map_x,  double map_y,
00176   double *alpha_channel, unsigned char sc[3], double colour[3],
00177   double *reflectivity, double *transparency,
00178   X__SHADER *lpEVI
00179 ){
00180  static
00181  vector pp[22]={{0.25,0.0,      0.0},                     //0
00182                 {0.75,0.0,      0.0},
00183                 {0.0, ROOT32/2, 0.0},
00184                 {0.5, ROOT32/2, 0.0},
00185                 {1.0, ROOT32/2, 0.0},
00186                 {0.25,ROOT32,   0.0},
00187                 {0.75,ROOT32,   0.0},
00188                 {0.0, 1.0/2.0/ROOT3-ROOT32/2,ROOT32/2.0},  //7
00189                 {0.5, 1.0/2.0/ROOT3-ROOT32/2,ROOT32/2.0},
00190                 {1.0, 1.0/2.0/ROOT3-ROOT32/2,ROOT32/2.0},
00191                 {0.25,1.0/2.0/ROOT3,         ROOT32/2.0},
00192                 {0.75,1.0/2.0/ROOT3,         ROOT32/2.0},
00193                 {0.0, 1.0/2.0/ROOT3+ROOT32/2,ROOT32/2.0}, //12
00194                 {0.5, 1.0/2.0/ROOT3+ROOT32/2,ROOT32/2.0},
00195                 {1.0, 1.0/2.0/ROOT3+ROOT32/2,ROOT32/2.0},
00196                 {0.25,0.0,      ROOT32},
00197                 {0.75,0.0,      ROOT32},
00198                 {0.0, ROOT32/2, ROOT32},
00199                 {0.5, ROOT32/2, ROOT32},
00200                 {1.0, ROOT32/2, ROOT32},
00201                 {0.25,ROOT32,   ROOT32},
00202                 {0.75,ROOT32,   ROOT32}};                 //21
00203  vector dn,vt;
00204  double dx,dy,dz,zb,ccc;
00205  long i;
00206  double a,cc,xx,yy,zz,r,g,b;
00207  vector u,v;
00208  cc=0.5;    // honeycomb + reptiles
00209 
00210  xx=alpha / x;
00211  yy=beta  / y;
00212  zz=gamma / z;
00213  xx += 0.16*sin(FMOD(2*zz,2*3.1415926));  // reptile
00214  yy += 0.16*cos(FMOD(3*xx,2*3.1415926));  // reptile
00215  zz += 0.16*cos(FMOD(4*yy,2*3.1415926));  // reptile
00216 
00217  yy /= ROOT32;
00218  xx=FMOD(xx,1.0);
00219  yy=FMOD(yy,ROOT32);
00220  zz /= ROOT32;
00221  zz=FMOD(zz,ROOT32);
00222  zb=0.0;
00223  r=c1[0];
00224  g=c1[1];
00225  b=c1[2];
00226  VECCOPY(n,dn)
00227  for(i=0;i<22;i++){
00228    dx=(xx-pp[i][0]);
00229    dy=(yy-pp[i][1]);
00230    dz=(zz-pp[i][2]);
00231    if((a=sqrt(dx*dx+dy*dy+dz*dz)) < cc){
00232      if((cc-a) > zb){
00233        zb=(cc-a);
00234        r=c2[0];
00235        g=c2[1];
00236        b=c2[2];
00237        if(a > 0.15){
00238          mix(&r,&g,&b,(a-0.15)/(cc-0.15),
00239           (double)c1[0],
00240           (double)c1[1],
00241           (double)c1[2],
00242           r,g,b);
00243 
00244        }
00245        v[0]=dx; v[1]=dy; v[2]=dz;
00246        VECCOPY(dn,n)
00247        normalize(v);
00248        VECSCALE(v[0],tAxis_unorm,vt)
00249        VECSUM(v[1]*tAxis_vnorm,vt,vt)
00250        VECSUM(-v[2]*tAxis_n,vt,vt)
00251        normalize(vt);
00252        VECCOPY(-vt,v)
00253        ccc=fabs(DOT(v,n));         // pimples + reptile
00254        CROSS(v,n,u)
00255        CROSS(n,u,v)
00256        normalize(v);
00257 //       a=0.4;                      // dimples + honey
00258 //       VECSCALE(a,v,v)             // dimples + honey
00259        a=1.8*a*sqrt(1.0-ccc*ccc);  // pimples + reptile
00260        VECSCALE(-a,v,v)            // pimples + reptile
00261        VECSCALE((1.0-a),n,n)
00262        VECSUM(v,n,n)
00263        normalize(n);
00264      }
00265    }
00266  }
00267  colour[0]  = r;
00268  colour[1]  = g;
00269  colour[2]  = b;
00270  return 1;
00271 }
00272 
00273 void _ExternalTextureClose(X__SHADER *lpEVI){
00274  UnloadCompiledShader(tGLshaderID);
00275 }
00276 
00277 long _ExternalTextureProcedureGL(
00278   double bump_scale,
00279   unsigned char sc[3],
00280   unsigned char ac[3],
00281   X__SHADER *lpEVI
00282 ){
00283  SetUniformVector(tGLshaderID,"C1",(GLfloat)c1[0]/255.0,(GLfloat)c1[1]/255.0,(GLfloat)c1[2]/255.0);
00284  SetUniformVector(tGLshaderID,"C2",(GLfloat)c2[0]/255.0,(GLfloat)c2[1]/255.0,(GLfloat)c2[2]/255.0);
00285  SetUniformVector(tGLshaderID,"C3",(GLfloat)c3[0]/255.0,(GLfloat)c3[1]/255.0,(GLfloat)c3[2]/255.0);
00286  SetUniformVector(tGLshaderID,"ScalingV",1.0/x,1.0/y,1.0/z);
00287  DrawShadedPolygons(tmatpass,tpass,tprogID,tattrloc,tNface,tMainFp,tNvert,tMainVp);
00288  return 1;
00289 }
00291 
00292 void CentreDialogOnScreen(HWND hwnd){
00293  RECT rcDlg;
00294  long Xres,Yres;
00295  Yres=GetSystemMetrics(SM_CYSCREEN);
00296  Xres=GetSystemMetrics(SM_CXSCREEN);
00297  GetWindowRect(hwnd,&rcDlg);
00298  OffsetRect(&rcDlg,-rcDlg.left,-rcDlg.top);
00299  OffsetRect(&rcDlg,(Xres-rcDlg.right)/2,(Yres-rcDlg.bottom)/2);
00300  SetWindowPos(hwnd,HWND_TOP,rcDlg.left,rcDlg.top,0,0,SWP_NOSIZE);
00301  return;
00302 }
00303 
00304 static void SetColour(double *colour, HWND parent){
00305  CHOOSECOLOR cc;
00306  static COLORREF CustColours[16]={
00307    RGB(255,255,255), RGB(239,239,239), RGB(223,223,223), RGB(207,207,207),
00308    RGB(191,191,191), RGB(175,175,175), RGB(159,159,159), RGB(143,143,143),
00309    RGB(127,127,127), RGB(111,111,111), RGB( 95, 95, 95), RGB( 79, 79, 79),
00310    RGB( 63, 63, 63), RGB( 47, 47, 47), RGB( 31, 31, 31), RGB( 15, 15, 15) };
00311  cc.lStructSize=sizeof(CHOOSECOLOR);
00312  cc.hwndOwner=parent;
00313  cc.rgbResult=RGB((BYTE)colour[0],(BYTE)colour[1],(BYTE)colour[2]);
00314  cc.lpCustColors=(LPDWORD)CustColours;
00315 // cc.Flags=CC_FULLOPEN | CC_RGBINIT | CC_ENABLEHOOK;
00316  cc.Flags= CC_RGBINIT;
00317  cc.lCustData=(DWORD)0;
00318  if(ChooseColor(&cc)){
00319    colour[0]=(double)GetRValue(cc.rgbResult);
00320    colour[1]=(double)GetGValue(cc.rgbResult);
00321    colour[2]=(double)GetBValue(cc.rgbResult);
00322  }
00323 }
00324 
00325 BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam);
00326 
00327 #if 0
00328 char * CALLBACK SetExternalParameters(
00329 #else
00330 char * _SetExternalParameters(
00331 #endif
00332   char *Op,                 /* string for the parameters                  */
00333   HWND hWnd,                /* parent window                              */
00334   X__MEMORY_MANAGER *lpEVI /* pointer to structure with memory functions */
00335                              ){
00336  char szbuf[255],*Op1;
00337  if(Op != NULL){  /* parameters exist so read them off the list */
00338    Op1=Op;
00339    Op1++;
00340    sscanf(Op1,"%f %f %f  %f %f  %f %f %f  %f %f %f   %f %f %f",
00341          &x,&y,&z,&size,&edge,
00342          &c1[0],&c1[1],&c1[2],
00343          &c2[0],&c2[1],&c2[2],
00344          &c3[0],&c3[1],&c3[2]);
00345  }
00346  if(DialogBox(hDLLinstance,MAKEINTRESOURCE(DLG),hWnd,
00347               (DLGPROC)DlgProc) == FALSE)return Op;
00348  if(Op != NULL)CALL_FREE(Op);  /* free the old string */
00349  sprintf(szbuf,"# %.2f %.2f %.2f  %.3f %.2f "
00350                  "%.2f %.2f %.2f "
00351                  "%.2f %.2f %.2f "
00352                  "%.2f %.2f %.2f",
00353          x,y,z,size,edge,
00354          c1[0],c1[1],c1[2],
00355          c2[0],c2[1],c2[2],
00356          c3[0],c3[1],c3[2]);
00357  if((Op=(char *)CALL_MALLOC(strlen(szbuf)+1)) == NULL){
00358   MessageBox (GetFocus(),"External shader: Out of memory","Error",
00359                 MB_OK|MB_TASKMODAL|MB_ICONSTOP);
00360    return NULL;
00361  }
00362  strcpy(Op,szbuf);
00363  return Op;
00364 }
00365 
00366 BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam){
00367  char str[16];
00368  switch( msg ) {
00369    case WM_INITDIALOG:
00370      sprintf(str,"%.2f",x);
00371      SendDlgItemMessage(hwnd,DLG_XSCALE,WM_SETTEXT,0,(LPARAM)str);
00372      SendDlgItemMessage(hwnd,DLG_XSCALE,EM_LIMITTEXT,(WPARAM)12,0);
00373      sprintf(str,"%.2f",y);
00374      SendDlgItemMessage(hwnd,DLG_YSCALE,WM_SETTEXT,0,(LPARAM)str);
00375      SendDlgItemMessage(hwnd,DLG_YSCALE,EM_LIMITTEXT,(WPARAM)12,0);
00376      sprintf(str,"%.2f",z);
00377      SendDlgItemMessage(hwnd,DLG_ZSCALE,WM_SETTEXT,0,(LPARAM)str);
00378      SendDlgItemMessage(hwnd,DLG_ZSCALE,EM_LIMITTEXT,(WPARAM)12,0);
00379      CentreDialogOnScreen(hwnd);
00380      return TRUE;
00381    case WM_DRAWITEM:{
00382        LPDRAWITEMSTRUCT lpdis;
00383        HBRUSH   hbr,hbrold;
00384        BYTE r,g,b;
00385        lpdis=(LPDRAWITEMSTRUCT)lparam;
00386        if(lpdis->CtlID == DLG_COLOUR1 ||
00387           lpdis->CtlID == DLG_COLOUR2){
00388          if(lpdis->CtlID == DLG_COLOUR1){
00389            r=(BYTE)c1[0]; g=(BYTE)c1[1]; b=(BYTE)c1[2];
00390          }
00391          else if(lpdis->CtlID == DLG_COLOUR2){
00392            r=(BYTE)c2[0]; g=(BYTE)c2[1]; b=(BYTE)c2[2];
00393          }
00394          if(lpdis->itemState & ODS_SELECTED)
00395             InvertRect(lpdis->hDC,&(lpdis->rcItem));
00396          else{
00397            hbr=CreateSolidBrush(RGB(r,g,b));
00398            hbrold=SelectObject(lpdis->hDC,hbr);
00399            Rectangle(lpdis->hDC,lpdis->rcItem.left,lpdis->rcItem.top,
00400                          lpdis->rcItem.right,lpdis->rcItem.bottom);
00401            SelectObject(lpdis->hDC,hbrold);
00402            DeleteObject(hbr);
00403          }
00404        }
00405      }
00406      break;
00407    case WM_COMMAND:
00408      switch(LOWORD(wparam)){
00409         case DLG_COLOUR1:
00410           SetColour(c1,hwnd);
00411           InvalidateRect(GetDlgItem(hwnd,DLG_COLOUR1),NULL,FALSE);
00412           break;
00413         case DLG_COLOUR2:
00414           SetColour(c2,hwnd);
00415           InvalidateRect(GetDlgItem(hwnd,DLG_COLOUR2),NULL,FALSE);
00416           break;
00417         case IDCANCEL:
00418           EndDialog(hwnd,FALSE);
00419           return(TRUE);
00420         case IDOK:
00421           if(GetDlgItemText(hwnd,DLG_XSCALE,str,10) == 0)
00422              EndDialog(hwnd,FALSE);
00423           if((x=atof(str)) == 0)EndDialog(hwnd,FALSE);
00424           if(GetDlgItemText(hwnd,DLG_YSCALE,str,10) == 0)
00425              EndDialog(hwnd,FALSE);
00426           if((y=atof(str)) == 0)EndDialog(hwnd,FALSE);
00427           if(GetDlgItemText(hwnd,DLG_ZSCALE,str,10) == 0)
00428              EndDialog(hwnd,FALSE);
00429           if((z=atof(str)) == 0)EndDialog(hwnd,FALSE);
00430           EndDialog(hwnd,TRUE);
00431           return(TRUE);
00432         default:
00433           break;
00434       }
00435       break;
00436     default: break;
00437  }
00438  return FALSE;
00439 }
Generated on Tue Jan 28 06:18:32 2014 for OpenFX by  doxygen 1.6.3