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