honey.c

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