brick2d.c

Go to the documentation of this file.
00001 /* --
00002 OpenFX - Modelling, Animation and Rendering Package
00003 -- */
00004 
00005 //  brick2d.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 "brick2d.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 static double ffmod(double x){
00058  if(x < 0){
00059    double a;
00060    a=fmod(-x,1.0);
00061    return 1.0-a;
00062  }
00063  return fmod(x,1.0);
00064 }
00065 
00066 static double step(double a, double x){
00067  if(x < a)return 0.0;
00068  return 1.0;
00069 }
00070 
00071 static void mix(double *r, double *g, double *b, double mx,
00072                 double r1, double g1, double b1,
00073                 double r2, double g2, double b2){
00074  *r = mx*r1 + (1.0-mx)*r2;
00075  *g = mx*g1 + (1.0-mx)*g2;
00076  *b = mx*b1 + (1.0-mx)*b2;
00077 }
00078 
00079 #if __WATCOMC__
00080 int APIENTRY LibMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00081 #else
00082 BOOL WINAPI DllMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00083 #endif
00084   HANDLE ghMod;
00085   switch (dwReason) {
00086     case DLL_PROCESS_ATTACH:
00087 #if __X__MIPS__
00088       if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00089 #endif
00090       hDLLinstance = hDLL;  /* handle to DLL file */
00091       break;
00092     case DLL_PROCESS_DETACH:
00093 #if __X__MIPS__
00094       if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00095 #endif
00096       break;
00097   }
00098   return (int)TRUE;
00099 }
00100 
00101 #if __SC__
00102 #pragma startaddress(DllMain)
00103 #endif
00104 
00105 static double thickness=0.1;
00106 static double c1[3]={255.0,255.0,255.0};
00107 static double x=1.0,y=1.0,z=1.0;
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",
00124          &x,&y,&z,&thickness,
00125          &c1[0],&c1[1],&c1[2]);
00126  }
00127  return LoadAndCompileShader("brick2d");
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 thickness_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",
00142         &x_m,&y_m,&z_m,&thickness_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  thickness=thickness_m+(thickness-thickness_m)*mr;
00146  x=x_m+(x-x_m)*mr;
00147  y=y_m+(y-y_m)*mr;
00148  z=z_m+(z-z_m)*mr;
00149  return 1;
00150 }
00151 
00152 #if 0
00153 long CALLBACK ExternalTextureProcedure(
00154 #else
00155 long _ExternalTextureProcedure(
00156 #endif
00157   long coord_type,  vector p, vector n,
00158   double alpha, double beta, double gamma,
00159   double bump,  double map_x,  double map_y,
00160   double *alpha_channel, unsigned char sc[3], double colour[3],
00161   double *reflectivity, double *transparency,
00162   X__SHADER *lpEVI
00163 ){
00164  long i;
00165  double a,cc,xx,yy,zz,noiseH,r,g,b;
00166  vector u,v;
00167  xx=alpha / x;
00168  yy=beta  / y;
00169  zz=gamma / z;
00170 {
00171   double ss,tt,tbrick,sbrick,w,h,mf=0.03;
00172   ss = xx / 1.0; tt= yy/ 1.0;
00173   if(ffmod(tt*0.5) > 0.5)ss += 0.5;
00174   tbrick=floor(tt);
00175   nNoise(0.0,tbrick*3,0.0,&noiseH);
00176   ss += 0.3*(noiseH - 0.5);
00177   sbrick=floor(ss);
00178   ss -= sbrick;
00179   tt -= tbrick;
00180   vNoise(v,10*xx,10*yy,0.5);
00181   ss += (v[0]-0.5)*0.02;
00182   tt += (v[1]-0.5)*0.02;
00183   w=step(mf,ss) - step(1-mf,ss);
00184   h=step(mf,tt) - step(1-mf,tt);
00185   mix(&r,&g,&b,w*h,
00186       (double)colour[0]/255.0,(double)colour[1]/255.0,(double)colour[2]/255.0,
00187       (double)c1[0]/255.0,(double)c1[1]/255.0,(double)c1[2]/255.0);
00188   if(w*h == 0){
00189     if(w == 0){
00190       if(ss < mf)  VECCOPY(-(1.0-ss/mf)*tAxis_unorm,v)
00191       if(ss > 1-mf)VECCOPY(((ss-(1.0-mf))/mf)*tAxis_unorm,v)
00192     }
00193     else{
00194       if(tt < mf)  VECCOPY((1.0-tt/mf)*tAxis_vnorm,v)
00195       if(tt > 1-mf)VECCOPY(-((tt-(1.0-mf))/mf)*tAxis_vnorm,v)
00196 //      VECCOPY(tAxis_vnorm,v)
00197     }
00198     VECSUM(n,0.5*v,n)
00199     vNoise(u,40*xx,40*yy,0.5);
00200     VECSUM(0.2*u,n,n)
00201     normalize(n);
00202   }
00203   else{
00204     vNoise(v,2*xx,2*yy,0.5);
00205     VECSCALE(0.2,v,v)
00206     VECSUM(n,v,n)
00207     vNoise(v,20*xx,20*yy,0.5);
00208     VECSCALE(0.1,v,v)
00209     VECSUM(n,v,n)
00210     if(ss > 1 - 2*mf)VECSUM(0.3*tAxis_unorm,n,n)
00211     else if(ss < 2*mf)VECSUM(-0.3*tAxis_unorm,n,n)
00212     else if(tt < 2*mf)VECSUM(0.3*tAxis_vnorm,n,n)
00213     else if(tt > 1 - 2*mf)VECSUM(-0.3*tAxis_vnorm,n,n)
00214     normalize(n);
00215     nNoise(xx*5,yy*5,0.5,&noiseH);
00216     r -= (noiseH*0.05);
00217     g -= (noiseH*0.05);
00218     b -= (noiseH*0.05);
00219   }
00220   r=max(r,0.0); g=max(g,0.0); b=max(b,0.0);
00221 }
00222  colour[0]  = r * 255.0;
00223  colour[1]  = g * 255.0;
00224  colour[2]  = b * 255.0;
00225  return 1;
00226 }
00227 
00228 void _ExternalTextureClose(X__SHADER *lpEVI){
00229  UnloadCompiledShader(tGLshaderID);
00230 }
00231 
00232 long _ExternalTextureProcedureGL(
00233   double bump_scale,
00234   unsigned char sc[3],
00235   unsigned char ac[3],
00236   X__SHADER *lpEVI
00237 ){
00238  // Set any shader specific uniform variables here.
00239  SetUniformVector(tGLshaderID,"MaterialC",(GLfloat)c1[0]/255.0,(GLfloat)c1[1]/255.0,(GLfloat)c1[2]/255.0);
00240  SetUniformVector(tGLshaderID,"ScalingV",1.0/x,1.0/z,1.0/y);
00241  SetUniformVariable(tGLshaderID,"Thickness",thickness);
00242  // Callback to Render the Polygons - this allows for multiple passes - through same shaders
00243  // possibly with different parameters - including vertex offset - blending depth enabling 
00244  // to allow for multipass textures e.g. hair and fur (shell model) it's arguments must not be altered!!!
00245  DrawShadedPolygons(tmatpass,tpass,tprogID,tattrloc,tNface,tMainFp,tNvert,tMainVp);
00246  return 1;
00247 }
00249 
00250 void CentreDialogOnScreen(HWND hwnd){
00251  RECT rcDlg;
00252  long Xres,Yres;
00253  Yres=GetSystemMetrics(SM_CYSCREEN);
00254  Xres=GetSystemMetrics(SM_CXSCREEN);
00255  GetWindowRect(hwnd,&rcDlg);
00256  OffsetRect(&rcDlg,-rcDlg.left,-rcDlg.top);
00257  OffsetRect(&rcDlg,(Xres-rcDlg.right)/2,(Yres-rcDlg.bottom)/2);
00258  SetWindowPos(hwnd,HWND_TOP,rcDlg.left,rcDlg.top,0,0,SWP_NOSIZE);
00259  return;
00260 }
00261 
00262 static void SetColour(double *colour, HWND parent){
00263  CHOOSECOLOR cc;
00264  static COLORREF CustColours[16]={
00265    RGB(255,255,255), RGB(239,239,239), RGB(223,223,223), RGB(207,207,207),
00266    RGB(191,191,191), RGB(175,175,175), RGB(159,159,159), RGB(143,143,143),
00267    RGB(127,127,127), RGB(111,111,111), RGB( 95, 95, 95), RGB( 79, 79, 79),
00268    RGB( 63, 63, 63), RGB( 47, 47, 47), RGB( 31, 31, 31), RGB( 15, 15, 15) };
00269  cc.lStructSize=sizeof(CHOOSECOLOR);
00270  cc.hwndOwner=parent;
00271  cc.rgbResult=RGB((BYTE)colour[0],(BYTE)colour[1],(BYTE)colour[2]);
00272  cc.lpCustColors=(LPDWORD)CustColours;
00273  cc.Flags= CC_RGBINIT;
00274  cc.lCustData=(DWORD)0;
00275  if(ChooseColor(&cc)){
00276    colour[0]=(double)GetRValue(cc.rgbResult);
00277    colour[1]=(double)GetGValue(cc.rgbResult);
00278    colour[2]=(double)GetBValue(cc.rgbResult);
00279  }
00280 }
00281 
00282 BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam);
00283 
00284 #if 0
00285 char * CALLBACK SetExternalParameters(
00286 #else
00287 char * _SetExternalParameters(
00288 #endif
00289   char *Op,                 /* string for the parameters                  */
00290   HWND hWnd,                /* parent window                              */
00291   X__MEMORY_MANAGER *lpEVI /* pointer to structure with memory functions */
00292                              ){
00293  char szbuf[255],*Op1;
00294  if(Op != NULL){  /* parameters exist so read them off the list */
00295    Op1=Op;
00296    Op1++;
00297    sscanf(Op1,"%f %f %f  %f  %f %f %f",
00298          &x,&y,&z,&thickness,
00299          &c1[0],&c1[1],&c1[2]);
00300  }
00301  if(DialogBox(hDLLinstance,MAKEINTRESOURCE(DLG),hWnd,
00302               (DLGPROC)DlgProc) == FALSE)return Op;
00303  if(Op != NULL)CALL_FREE(Op);  /* free the old string */
00304  sprintf(szbuf,"# %.2f %.2f %.2f  %.3f "
00305                  "%.2f %.2f %.2f ",
00306          x,y,z,thickness,
00307          c1[0],c1[1],c1[2]);
00308  if((Op=(char *)CALL_MALLOC(strlen(szbuf)+1)) == NULL){
00309   MessageBox (GetFocus(),"External shader: Out of memory","Error",
00310                 MB_OK|MB_TASKMODAL|MB_ICONSTOP);
00311    return NULL;
00312  }
00313  strcpy(Op,szbuf);
00314  return Op;
00315 }
00316 
00317 BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam){
00318  char str[16];
00319  switch( msg ) {
00320    case WM_INITDIALOG:
00321      sprintf(str,"%.2f",x);
00322      SendDlgItemMessage(hwnd,DLG_XSCALE,WM_SETTEXT,0,(LPARAM)str);
00323      SendDlgItemMessage(hwnd,DLG_XSCALE,EM_LIMITTEXT,(WPARAM)12,0);
00324      sprintf(str,"%.2f",y);
00325      SendDlgItemMessage(hwnd,DLG_YSCALE,WM_SETTEXT,0,(LPARAM)str);
00326      SendDlgItemMessage(hwnd,DLG_YSCALE,EM_LIMITTEXT,(WPARAM)12,0);
00327      sprintf(str,"%.2f",z);
00328      SendDlgItemMessage(hwnd,DLG_ZSCALE,WM_SETTEXT,0,(LPARAM)str);
00329      SendDlgItemMessage(hwnd,DLG_ZSCALE,EM_LIMITTEXT,(WPARAM)12,0);
00330      CentreDialogOnScreen(hwnd);
00331      return TRUE;
00332    case WM_DRAWITEM:{
00333        LPDRAWITEMSTRUCT lpdis;
00334        HBRUSH   hbr,hbrold;
00335        BYTE r,g,b;
00336        lpdis=(LPDRAWITEMSTRUCT)lparam;
00337        if(lpdis->CtlID == DLG_COLOUR1){
00338          if(lpdis->CtlID == DLG_COLOUR1){
00339            r=(BYTE)c1[0]; g=(BYTE)c1[1]; b=(BYTE)c1[2];
00340          }
00341          if(lpdis->itemState & ODS_SELECTED)
00342             InvertRect(lpdis->hDC,&(lpdis->rcItem));
00343          else{
00344            hbr=CreateSolidBrush(RGB(r,g,b));
00345            hbrold=SelectObject(lpdis->hDC,hbr);
00346            Rectangle(lpdis->hDC,lpdis->rcItem.left,lpdis->rcItem.top,
00347                          lpdis->rcItem.right,lpdis->rcItem.bottom);
00348            SelectObject(lpdis->hDC,hbrold);
00349            DeleteObject(hbr);
00350          }
00351        }
00352      }
00353      break;
00354    case WM_COMMAND:
00355      switch(LOWORD(wparam)){
00356         case DLG_COLOUR1:
00357           SetColour(c1,hwnd);
00358           InvalidateRect(GetDlgItem(hwnd,DLG_COLOUR1),NULL,FALSE);
00359           break;
00360         case IDCANCEL:
00361           EndDialog(hwnd,FALSE);
00362           return(TRUE);
00363         case IDOK:
00364           if(GetDlgItemText(hwnd,DLG_XSCALE,str,10) == 0)
00365              EndDialog(hwnd,FALSE);
00366           if((x=atof(str)) == 0)EndDialog(hwnd,FALSE);
00367           if(GetDlgItemText(hwnd,DLG_YSCALE,str,10) == 0)
00368              EndDialog(hwnd,FALSE);
00369           if((y=atof(str)) == 0)EndDialog(hwnd,FALSE);
00370           if(GetDlgItemText(hwnd,DLG_ZSCALE,str,10) == 0)
00371              EndDialog(hwnd,FALSE);
00372           if((z=atof(str)) == 0)EndDialog(hwnd,FALSE);
00373           EndDialog(hwnd,TRUE);
00374           return(TRUE);
00375         default:
00376           break;
00377       }
00378       break;
00379     default: break;
00380  }
00381  return FALSE;
00382 }
Generated on Tue Jan 28 06:18:31 2014 for OpenFX by  doxygen 1.6.3