leopard.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 // leopard.c
00025 
00026 
00027 #include <stdlib.h>
00028 #include <stdio.h>
00029 #include <math.h>
00030 #include <float.h>
00031 #include <windows.h>
00032 #include <gl/gl.h>
00033 
00034 #if __ZTC__ || __SC__
00035 #ifndef max
00036 #define max(a,b)  ( ((a) > (b)) ? (a) : (b) )
00037 #endif
00038 #endif
00039 
00040 #if __WATCOMC__
00041 #define PI 3.1415926
00042 #endif
00043 
00044 #if __X__MIPS__
00045 BOOL WINAPI _CRT_INIT(HINSTANCE ,DWORD , LPVOID );
00046 #endif
00047 
00048 static HINSTANCE hDLLinstance=NULL;
00049 
00050 #include "..\animate\memory.h" /* for memory definition */
00051 #include "..\animate\memdef.h" /* local names           */
00052 #include "defines.h"
00053 #include "rstruct.h"
00054 #include "leopard.h"
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 double sharpness=0.0,coverage=0.8;
00105 static double c1[3]={251.0,162.0,12.0};
00106 static double x=1.0,y=1.0,z=1.0;
00107 
00108 
00109 #if 0
00110 long CALLBACK ExternalTextureStartup(
00111 #else
00112 long _ExternalTextureStartup(
00113 #endif
00114   long frame,long nframes,char *parameter_list, X__SHADER *lpEVI){
00115  if(parameter_list[0] != '#'){
00116    MessageBox ( GetFocus(),
00117                 (LPCTSTR) "External texture: Startup",
00118                 (LPCTSTR) "Parameter list missing",
00119                 MB_OK | MB_SYSTEMMODAL );
00120  }
00121  else {
00122   parameter_list++;
00123   sscanf(parameter_list,"%f %f %f  %f %f  %f %f %f",
00124          &x,&y,&z,&coverage,&sharpness,
00125          &c1[0],&c1[1],&c1[2]);
00126  }
00127  return LoadAndCompileShader("leopard");
00128 }
00129 
00130 #if 0
00131 long CALLBACK ExternalTextureMorph(
00132 #else
00133 long _ExternalTextureMorph(
00134 #endif
00135  char *parameter_list, double mr){
00136  int i;
00137  double coverage_m,sharpness_m;
00138  double c1_m[3];
00139  double x_m,y_m,z_m;
00140  parameter_list++;
00141  sscanf(parameter_list,"%f %f %f  %f %f  %f %f %f",
00142         &x_m,&y_m,&z_m,&coverage_m,&sharpness_m,
00143         &c1_m[0],&c1_m[1],&c1_m[2]);
00144  for(i=0;i<3;i++)c1[i]=c1_m[i]+(c1[i]-c1_m[i])*mr;
00145  coverage=coverage_m+(coverage-coverage_m)*mr;
00146  sharpness=sharpness_m+(sharpness-sharpness_m)*mr;
00147  x=x_m+(x-x_m)*mr;
00148  y=y_m+(y-y_m)*mr;
00149  z=z_m+(z-z_m)*mr;
00150  return 1;
00151 }
00152 
00153 static void mix(double *r, double *g, double *b, double mx,
00154                 double r1, double g1, double b1,
00155                 double r2, double g2, double b2){
00156  *r = mx*r1 + (1.0-mx)*r2;
00157  *g = mx*g1 + (1.0-mx)*g2;
00158  *b = mx*b1 + (1.0-mx)*b2;
00159 }
00160 
00161 #if 0
00162 long CALLBACK ExternalTextureProcedure(
00163 #else
00164 long _ExternalTextureProcedure(
00165 #endif
00166   long coord_type,  vector p, vector n,
00167   double alpha, double beta, double gamma,
00168   double bump,  double map_x,  double map_y,
00169   double *alpha_channel, unsigned char sc[3], double colour[3],
00170   double *reflectivity, double *transparency,
00171   X__SHADER *lpEVI
00172 ){
00173  // leopard skin
00174  static
00175  vector pp[22]={{0.25,0.0,      0.0},                     //0
00176                 {0.75,0.0,      0.0},
00177                 {0.0, ROOT32/2, 0.0},
00178                 {0.5, ROOT32/2, 0.0},
00179                 {1.0, ROOT32/2, 0.0},
00180                 {0.25,ROOT32,   0.0},
00181                 {0.75,ROOT32,   0.0},
00182                 {0.0, 1.0/2.0/ROOT3-ROOT32/2,ROOT32/2.0},  //7
00183                 {0.5, 1.0/2.0/ROOT3-ROOT32/2,ROOT32/2.0},
00184                 {1.0, 1.0/2.0/ROOT3-ROOT32/2,ROOT32/2.0},
00185                 {0.25,1.0/2.0/ROOT3,         ROOT32/2.0},
00186                 {0.75,1.0/2.0/ROOT3,         ROOT32/2.0},
00187                 {0.0, 1.0/2.0/ROOT3+ROOT32/2,ROOT32/2.0}, //12
00188                 {0.5, 1.0/2.0/ROOT3+ROOT32/2,ROOT32/2.0},
00189                 {1.0, 1.0/2.0/ROOT3+ROOT32/2,ROOT32/2.0},
00190                 {0.25,0.0,      ROOT32},
00191                 {0.75,0.0,      ROOT32},
00192                 {0.0, ROOT32/2, ROOT32},
00193                 {0.5, ROOT32/2, ROOT32},
00194                 {1.0, ROOT32/2, ROOT32},
00195                 {0.25,ROOT32,   ROOT32},
00196                 {0.75,ROOT32,   ROOT32}};                 //21
00197  static double cc=0.25;
00198  double dx,dy,dz,zb;
00199  long i;
00200  double a,xx,yy,zz,r,g,b;
00201  xx=alpha / x;
00202  yy=beta  / y;
00203  zz=gamma / z;
00204  xx += 0.11*sin(FMOD(3*zz,2*3.1415926));
00205  xx += 0.2*sin(FMOD(0.1*yy,2*3.1415926));
00206  yy += 0.15*cos(FMOD(4*xx,2*3.1415926));
00207  yy += 0.2*sin(FMOD(0.1*zz,2*3.1415926));
00208  zz += 0.18*cos(FMOD(5*yy,2*3.1415926));
00209  zz += 0.2*sin(FMOD(0.1*xx,2*3.1415926));
00210  yy /= ROOT32;
00211  xx=FMOD(xx,1.0);
00212  yy=FMOD(yy,ROOT32);
00213  zz /= ROOT32;
00214  zz=FMOD(zz,ROOT32);
00215  zb=0.0;
00216  r=colour[0];
00217  g=colour[1];
00218  b=colour[2];
00219  for(i=0;i<22;i++){
00220    dx=(xx-pp[i][0]);
00221    dy=(yy-pp[i][1]);
00222    dz=(zz-pp[i][2]);
00223    if(fabs(dx) > cc)continue;
00224    if(fabs(dy) > cc)continue;
00225    if(fabs(dz) > cc)continue;
00226    if((a=sqrt(dx*dx+dy*dy+dz*dz)) < cc){
00227      if((cc-a) > zb){
00228        zb=(cc-a);
00229        r=c1[0];
00230        g=c1[1];
00231        b=c1[2];
00232        if(a > 0.20){
00233          mix(&r,&g,&b,(a-0.20)/(cc-0.20),
00234           (double)colour[0],
00235           (double)colour[1],
00236           (double)colour[2],
00237           r,g,b);
00238        }
00239      }
00240    }
00241  }
00242  colour[0]  = r;
00243  colour[1]  = g;
00244  colour[2]  = b;
00245  return 1;
00246 }
00247 
00248 void _ExternalTextureClose(X__SHADER *lpEVI){
00249  UnloadCompiledShader(tGLshaderID);
00250 }
00251 
00252 long _ExternalTextureProcedureGL(
00253   double bump_scale,
00254   unsigned char sc[3],
00255   unsigned char ac[3],
00256   X__SHADER *lpEVI
00257 ){
00258  // Set any shader specific uniform variables here.
00259  SetUniformVector(tGLshaderID,"MaterialC",(GLfloat)c1[0]/255.0,(GLfloat)c1[1]/255.0,(GLfloat)c1[2]/255.0);
00260  SetUniformVector(tGLshaderID,"ScalingV",1.0/x,1.0/y,1.0/z);
00261  DrawShadedPolygons(tmatpass,tpass,tprogID,tattrloc,tNface,tMainFp,tNvert,tMainVp);
00262  return 1;
00263 }
00265 
00266 void CentreDialogOnScreen(HWND hwnd){
00267  RECT rcDlg;
00268  long Xres,Yres;
00269  Yres=GetSystemMetrics(SM_CYSCREEN);
00270  Xres=GetSystemMetrics(SM_CXSCREEN);
00271  GetWindowRect(hwnd,&rcDlg);
00272  OffsetRect(&rcDlg,-rcDlg.left,-rcDlg.top);
00273  OffsetRect(&rcDlg,(Xres-rcDlg.right)/2,(Yres-rcDlg.bottom)/2);
00274  SetWindowPos(hwnd,HWND_TOP,rcDlg.left,rcDlg.top,0,0,SWP_NOSIZE);
00275  return;
00276 }
00277 
00278 static void SetColour(double *colour, HWND parent){
00279  CHOOSECOLOR cc;
00280  static COLORREF CustColours[16]={
00281    RGB(255,255,255), RGB(239,239,239), RGB(223,223,223), RGB(207,207,207),
00282    RGB(191,191,191), RGB(175,175,175), RGB(159,159,159), RGB(143,143,143),
00283    RGB(127,127,127), RGB(111,111,111), RGB( 95, 95, 95), RGB( 79, 79, 79),
00284    RGB( 63, 63, 63), RGB( 47, 47, 47), RGB( 31, 31, 31), RGB( 15, 15, 15) };
00285  cc.lStructSize=sizeof(CHOOSECOLOR);
00286  cc.hwndOwner=parent;
00287  cc.rgbResult=RGB((BYTE)colour[0],(BYTE)colour[1],(BYTE)colour[2]);
00288  cc.lpCustColors=(LPDWORD)CustColours;
00289  cc.Flags= CC_RGBINIT;
00290  cc.lCustData=(DWORD)0;
00291  if(ChooseColor(&cc)){
00292    colour[0]=(double)GetRValue(cc.rgbResult);
00293    colour[1]=(double)GetGValue(cc.rgbResult);
00294    colour[2]=(double)GetBValue(cc.rgbResult);
00295  }
00296 }
00297 
00298 BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam);
00299 
00300 #if 0
00301 char * CALLBACK SetExternalParameters(
00302 #else
00303 char * _SetExternalParameters(
00304 #endif
00305   char *Op,                 /* string for the parameters                  */
00306   HWND hWnd,                /* parent window                              */
00307   X__MEMORY_MANAGER *lpEVI /* pointer to structure with memory functions */
00308                              ){
00309  char szbuf[255],*Op1;
00310  if(Op != NULL){  /* parameters exist so read them off the list */
00311    Op1=Op;
00312    Op1++;
00313    sscanf(Op1,"%f %f %f  %f %f  %f %f %f",
00314          &x,&y,&z,&coverage,&sharpness,
00315          &c1[0],&c1[1],&c1[2]);
00316  }
00317  if(DialogBox(hDLLinstance,MAKEINTRESOURCE(DLG),hWnd,
00318               (DLGPROC)DlgProc) == FALSE)return Op;
00319  if(Op != NULL)CALL_FREE(Op);  /* free the old string */
00320  sprintf(szbuf,"# %.2f %.2f %.2f  %.3f %.2f "
00321                  "%.2f %.2f %.2f ",
00322          x,y,z,coverage,sharpness,
00323          c1[0],c1[1],c1[2]);
00324  if((Op=(char *)CALL_MALLOC(strlen(szbuf)+1)) == NULL){
00325   MessageBox (GetFocus(),"External shader: Out of memory","Error",
00326                 MB_OK|MB_TASKMODAL|MB_ICONSTOP);
00327    return NULL;
00328  }
00329  strcpy(Op,szbuf);
00330  return Op;
00331 }
00332 
00333 BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam){
00334  char str[16];
00335  switch( msg ) {
00336    case WM_INITDIALOG:
00337      CentreDialogOnScreen(hwnd);
00338      return TRUE;
00339    case WM_DRAWITEM:{
00340        LPDRAWITEMSTRUCT lpdis;
00341        HBRUSH   hbr,hbrold;
00342        BYTE r,g,b;
00343        lpdis=(LPDRAWITEMSTRUCT)lparam;
00344        if(lpdis->CtlID == DLG_COLOUR1){
00345          if(lpdis->CtlID == DLG_COLOUR1){
00346            r=(BYTE)c1[0]; g=(BYTE)c1[1]; b=(BYTE)c1[2];
00347          }
00348          if(lpdis->itemState & ODS_SELECTED)
00349             InvertRect(lpdis->hDC,&(lpdis->rcItem));
00350          else{
00351            hbr=CreateSolidBrush(RGB(r,g,b));
00352            hbrold=SelectObject(lpdis->hDC,hbr);
00353            Rectangle(lpdis->hDC,lpdis->rcItem.left,lpdis->rcItem.top,
00354                          lpdis->rcItem.right,lpdis->rcItem.bottom);
00355            SelectObject(lpdis->hDC,hbrold);
00356            DeleteObject(hbr);
00357          }
00358        }
00359      }
00360      break;
00361    case WM_COMMAND:
00362      switch(LOWORD(wparam)){
00363         case DLG_COLOUR1:
00364           SetColour(c1,hwnd);
00365           InvalidateRect(GetDlgItem(hwnd,DLG_COLOUR1),NULL,FALSE);
00366           break;
00367         case IDCANCEL:
00368           EndDialog(hwnd,FALSE);
00369           return(TRUE);
00370         case IDOK:
00371           EndDialog(hwnd,TRUE);
00372           return(TRUE);
00373         default:
00374           break;
00375       }
00376       break;
00377     default: break;
00378  }
00379  return FALSE;
00380 }
00381 
00382 
Generated on Tue Jan 28 06:18:32 2014 for OpenFX by  doxygen 1.6.3