moon.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 // moon.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 #include "defines.h"
00034 #include "rstruct.h"
00035 #include "moon.h"
00036 
00037 #define VECCOPY(a,b)    { b[0] = a[0]; b[1] = a[1]; b[2] = a[2]; }
00038 #define VECSUM(a,b,c)   { c[0]=a[0]+b[0]; c[1]=a[1]+b[1]; c[2]=a[2]+b[2];}
00039 #define VECSUB(a,b,c)   { c[0]=a[0]-b[0]; c[1]=a[1]-b[1]; c[2]=a[2]-b[2];}
00040 #define VECSCALE(a,b,c) { c[0]=(a)*b[0]; c[1]=(a)*b[1]; c[2]=(a)*b[2];}
00041 #define DOT(a,b)        ( (a[0]*b[0]) + (a[1]*b[1]) + (a[2]*b[2]) )
00042 
00043 #define IMOD(z,a) ((z) - ((z)/(a))*(a))
00044 #define PATTERN(x,y,z)   ( ((z)+16384L)*64536L +  \
00045                            ((y)+16384L)*32768L +  \
00046                            ((x)+16384L))
00047 #define FLOOR(x) ((x) >= 0.0 ? floor(x) : (0.0 - floor(0.0 - (x)) - 1.0))
00048 #define FMOD(x,a) ((x) >= 0.0 ? fmod(x,a) :(a - fmod(-(x),a)))
00049 
00050 #include "randno.c"
00051 
00052 static long ip[27][3]={
00053    { 0, 0, 0},
00054    { 1, 0, 0},
00055    { 1, 1, 0},
00056    { 0, 1, 0},
00057    {-1, 1, 0},
00058    {-1, 0, 0},
00059    {-1,-1, 0},
00060    { 0,-1, 0},
00061    { 1,-1, 0},
00062    { 0, 0,-1},
00063    { 1, 0,-1},
00064    { 1, 1,-1},
00065    { 0, 1,-1},
00066    {-1, 1,-1},
00067    {-1, 0,-1},
00068    {-1,-1,-1},
00069    { 0,-1,-1},
00070    { 1,-1,-1},
00071    { 0, 0, 1},
00072    { 1, 0, 1},
00073    { 1, 1, 1},
00074    { 0, 1, 1},
00075    {-1, 1, 1},
00076    {-1, 0, 1},
00077    {-1,-1, 1},
00078    { 0,-1, 1},
00079    { 1,-1, 1}
00080  };
00081 
00082 #if __WATCOMC__
00083 int APIENTRY LibMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00084 #else
00085 BOOL WINAPI DllMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00086 #endif
00087   HANDLE ghMod;
00088   switch (dwReason) {
00089     case DLL_PROCESS_ATTACH:
00090 #if __X__MIPS__
00091       if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00092 #endif
00093       hDLLinstance = hDLL;  /* handle to DLL file */
00094       break;
00095     case DLL_PROCESS_DETACH:
00096 #if __X__MIPS__
00097       if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00098 #endif
00099       break;
00100   }
00101   return (int)TRUE;
00102 }
00103 
00104 #if __SC__
00105 #pragma startaddress(DllMain)
00106 #endif
00107 
00108 static double x=1.0,y=1.0,z=1.0,c1[3]={127.0,127.0,127.0};
00109 
00110 #if 0
00111 long CALLBACK ExternalTextureStartup(
00112 #else
00113 long _ExternalTextureStartup(
00114 #endif
00115   long frame,long nframes,char *parameter_list, X__SHADER *lpEVI){
00116  if(parameter_list[0] != '#'){
00117    MessageBox ( GetFocus(),
00118                 (LPCTSTR) "External texture: Startup",
00119                 (LPCTSTR) "Parameter list missing",
00120                 MB_OK | MB_SYSTEMMODAL );
00121  }
00122  else {
00123   parameter_list++;
00124   sscanf(parameter_list,"%f %f %f %f %f %f",
00125          &x,&y,&z,&c1[0],&c1[1],&c1[2]);
00126  }
00127  return LoadAndCompileShader("moon");
00128 }
00129 
00130 #if 0
00131 long CALLBACK ExternalTextureMorph(
00132 #else
00133 long _ExternalTextureMorph(
00134 #endif
00135  char *parameter_list, double mr){
00136  double x_m,y_m,z_m,c1_m[3];
00137  parameter_list++;
00138  sscanf(parameter_list,"%f %f %f %f %f %f",
00139         &x_m,&y_m,&z_m,&c1[0],&c1[1],&c1[2]);
00140  x=x_m+(x-x_m)*mr;
00141  y=y_m+(y-y_m)*mr;
00142  z=z_m+(z-z_m)*mr;
00143  return 1;
00144 }
00145 
00146 #if 0
00147 long CALLBACK ExternalTextureProcedure(
00148 #else
00149 long _ExternalTextureProcedure(
00150 #endif
00151   long coord_type,  vector p, vector n,
00152   double alpha, double beta, double gamma,
00153   double bump,  double map_x,  double map_y,
00154   double *alpha_channel, unsigned char sc[3], double colour[3],
00155   double *reflectivity, double *transparency,
00156   X__SHADER *lpEVI
00157 ){
00158  static long N=1;
00159 // static double bradius=0.4,lradius=0.3;
00160  static double bradius=0.235,lradius=0.125,turb=1.0;
00161  double a;
00162  vector u,v,t;
00163  double xx,yy,zz,r,g,b;
00164  double  dpoint[27];
00165  double dradius[27];
00166  vector pp[27];
00167  double dx,dy,dz,cx,cy,cz,zb,ccc,dc,zbb,radius,noiseH,noiseC,noiseHH;
00168  long i,ix,iy,iz;
00169  BOOL ins1;
00170  long k,j,jid,id,pattern,patterni;
00171  double len,rad;
00172  vector ppc;
00173 
00174  xx=alpha / x;
00175  yy=beta  / y;
00176  zz=gamma / z;
00177 
00178  r=c1[0]/255.0;
00179  g=c1[1]/255.0;
00180  b=c1[2]/255.0;
00181 
00182  {
00183    vTurbulence(t, xx, yy, zz);
00184    dx = xx + t[0] * turb;
00185    dy = yy + t[1] * turb;
00186    dz = zz + t[2] * turb;
00187    nNoise(dx,dy,dz,&noiseH);
00188    if(noiseH > 0.6){
00189      r += 0.1;
00190      g += 0.1;
00191      b += 0.1;
00192    }
00193  }
00194 
00195  nNoise(xx*7,yy*7,zz*7,&noiseH);
00196  noiseH *= 0.2;
00197  nNoise(xx*15,yy*15,zz*15,&noiseHH);
00198  noiseC=0.18+(noiseHH-0.5)*0.11;
00199  ins1=FALSE;
00200 
00201  for(k=0;k<3;k++){
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  id = -1;
00212  len=sqrt(tAxis_u[0]*tAxis_u[0]+
00213           tAxis_u[1]*tAxis_u[1]+
00214           tAxis_u[2]*tAxis_u[2]);
00215  VECCOPY(-tAxis_n,u)
00216  VECSCALE(len,u,u)         // third axis
00217  VECCOPY(tAxis_o,v)
00218  VECSUM(v,cx*tAxis_u,v)
00219  VECSUM(v,cy*tAxis_v,v)
00220  VECSUM(v,cz*u,v)         // coord of point on surface
00221  for(j=0;j<27;j++){
00222  pattern=PATTERN(ix+ip[j][0],iy+ip[j][1],iz+ip[j][2]);
00223  pattern=IMOD(N*pattern,1900);
00224  for(i=0;i<N;i++){
00225    jid=j*N+i;
00226    patterni=pattern+i;
00227    VECSUM((double)ip[j],rand_v[patterni],ppc)
00228    VECSUM(tAxis_o,ppc[0]*tAxis_u,pp[jid])
00229    VECSUM(pp[jid],ppc[1]*tAxis_v,pp[jid])
00230    VECSUM(pp[jid],ppc[2]*u,      pp[jid])
00231 
00232    radius=(bradius+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 && !ins1){
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          VECSCALE(-1.0,dn,dn);
00272 //         if(a < 0.06){
00273          if(a < 0.1){
00274            a=0.1;  // crater edge
00275          }
00276          else{     // inside crater
00277            a=1;
00278          }
00279          ins1=TRUE;
00280          VECSUM((1.0-a)*dn,(a)*n,n)
00281          normalize(n);
00282        }
00283      }
00284    }
00285  }
00286 
00287  xx *= 2.0;
00288  yy *= 2.0;
00289  zz *= 2.0;
00290  }
00291 
00292  if(ins1){
00293    r -= noiseC;
00294    g -= noiseC;
00295    b -= noiseC;
00296  }
00297  else{
00298    r -= noiseH;
00299    g -= noiseH;
00300    b -= noiseH;
00301  }
00302  r=max(r,0.0); g=max(g,0.0); b=max(b,0.0);
00303 
00304  colour[0] = r*255.0;
00305  colour[1] = g*255.0;
00306  colour[2] = b*255.0;
00307  return 1;
00308 }
00309 
00310 void _ExternalTextureClose(X__SHADER *lpEVI){
00311  UnloadCompiledShader(tGLshaderID);
00312 }
00313 
00314 long _ExternalTextureProcedureGL(
00315   double bump_scale,
00316   unsigned char sc[3],
00317   unsigned char ac[3],
00318   X__SHADER *lpEVI
00319 ){
00320  SetUniformVector(tGLshaderID,"MaterialC",(GLfloat)ac[0]/255.0,(GLfloat)ac[1]/255.0,(GLfloat)ac[2]/255.0);
00321  SetUniformVector(tGLshaderID,"ScalingV",1.0/x,1.0/z,1.0/y);
00322  DrawShadedPolygons(tmatpass,tpass,tprogID,tattrloc,tNface,tMainFp,tNvert,tMainVp);
00323  return 1;
00324 }
00326 
00327 void CentreDialogOnScreen(HWND hwnd){
00328  RECT rcDlg;
00329  long Xres,Yres;
00330  Yres=GetSystemMetrics(SM_CYSCREEN);
00331  Xres=GetSystemMetrics(SM_CXSCREEN);
00332  GetWindowRect(hwnd,&rcDlg);
00333  OffsetRect(&rcDlg,-rcDlg.left,-rcDlg.top);
00334  OffsetRect(&rcDlg,(Xres-rcDlg.right)/2,(Yres-rcDlg.bottom)/2);
00335  SetWindowPos(hwnd,HWND_TOP,rcDlg.left,rcDlg.top,0,0,SWP_NOSIZE);
00336  return;
00337 }
00338 
00339 static void SetColour(double *colour, HWND parent){
00340  CHOOSECOLOR cc;
00341  static COLORREF CustColours[16]={
00342    RGB(255,255,255), RGB(239,239,239), RGB(223,223,223), RGB(207,207,207),
00343    RGB(191,191,191), RGB(175,175,175), RGB(159,159,159), RGB(143,143,143),
00344    RGB(127,127,127), RGB(111,111,111), RGB( 95, 95, 95), RGB( 79, 79, 79),
00345    RGB( 63, 63, 63), RGB( 47, 47, 47), RGB( 31, 31, 31), RGB( 15, 15, 15) };
00346  cc.lStructSize=sizeof(CHOOSECOLOR);
00347  cc.hwndOwner=parent;
00348  cc.rgbResult=RGB((BYTE)colour[0],(BYTE)colour[1],(BYTE)colour[2]);
00349  cc.lpCustColors=(LPDWORD)CustColours;
00350  cc.Flags= CC_RGBINIT;
00351  cc.lCustData=(DWORD)0;
00352  if(ChooseColor(&cc)){
00353    colour[0]=(double)GetRValue(cc.rgbResult);
00354    colour[1]=(double)GetGValue(cc.rgbResult);
00355    colour[2]=(double)GetBValue(cc.rgbResult);
00356  }
00357 }
00358 
00359 BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam);
00360 
00361 #if 0
00362 char * CALLBACK SetExternalParameters(
00363 #else
00364 char * _SetExternalParameters(
00365 #endif
00366   char *Op,                 /* string for the parameters                  */
00367   HWND hWnd,                /* parent window                              */
00368   X__MEMORY_MANAGER *lpEVI /* pointer to structure with memory functions */
00369                              ){
00370  char szbuf[255],*Op1;
00371  if(Op != NULL){  /* parameters exist so read them off the list */
00372    Op1=Op;
00373    Op1++;
00374    sscanf(Op1,"%f %f %f",
00375          &x,&y,&z,&c1[0],&c1[1],&c1[2]);
00376  }
00377  if(DialogBox(hDLLinstance,MAKEINTRESOURCE(DLG),hWnd,
00378               (DLGPROC)DlgProc) == FALSE)return Op;
00379  if(Op != NULL)CALL_FREE(Op);  /* free the old string */
00380  sprintf(szbuf,"# %.3f %.3f %.3f %.2 %.2 %.2",
00381          x,y,z,c1[0],c1[1],c1[2]);
00382  if((Op=(char *)CALL_MALLOC(strlen(szbuf)+1)) == NULL){
00383   MessageBox (GetFocus(),"External shader: Out of memory","Error",
00384                 MB_OK|MB_TASKMODAL|MB_ICONSTOP);
00385    return NULL;
00386  }
00387  strcpy(Op,szbuf);
00388  return Op;
00389 }
00390 
00391 BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam){
00392  char str[16];
00393  switch( msg ) {
00394    case WM_INITDIALOG:
00395      sprintf(str,"%.2f",x);
00396      SendDlgItemMessage(hwnd,DLG_XSCALE,WM_SETTEXT,0,(LPARAM)str);
00397      SendDlgItemMessage(hwnd,DLG_XSCALE,EM_LIMITTEXT,(WPARAM)12,0);
00398      sprintf(str,"%.2f",y);
00399      SendDlgItemMessage(hwnd,DLG_YSCALE,WM_SETTEXT,0,(LPARAM)str);
00400      SendDlgItemMessage(hwnd,DLG_YSCALE,EM_LIMITTEXT,(WPARAM)12,0);
00401      sprintf(str,"%.2f",z);
00402      SendDlgItemMessage(hwnd,DLG_ZSCALE,WM_SETTEXT,0,(LPARAM)str);
00403      SendDlgItemMessage(hwnd,DLG_ZSCALE,EM_LIMITTEXT,(WPARAM)12,0);
00404      CentreDialogOnScreen(hwnd);
00405      return TRUE;
00406    case WM_DRAWITEM:{
00407        LPDRAWITEMSTRUCT lpdis;
00408        HBRUSH   hbr,hbrold;
00409        BYTE r,g,b;
00410        lpdis=(LPDRAWITEMSTRUCT)lparam;
00411        if(lpdis->CtlID == DLG_COLOUR){
00412          if(lpdis->CtlID == DLG_COLOUR){
00413            r=(BYTE)c1[0]; g=(BYTE)c1[1]; b=(BYTE)c1[2];
00414          }
00415          if(lpdis->itemState & ODS_SELECTED)
00416             InvertRect(lpdis->hDC,&(lpdis->rcItem));
00417          else{
00418            hbr=CreateSolidBrush(RGB(r,g,b));
00419            hbrold=SelectObject(lpdis->hDC,hbr);
00420            Rectangle(lpdis->hDC,lpdis->rcItem.left,lpdis->rcItem.top,
00421                          lpdis->rcItem.right,lpdis->rcItem.bottom);
00422            SelectObject(lpdis->hDC,hbrold);
00423            DeleteObject(hbr);
00424          }
00425        }
00426      }
00427      break;
00428    case WM_COMMAND:
00429      switch(LOWORD(wparam)){
00430         case DLG_COLOUR:
00431           SetColour(c1,hwnd);
00432           InvalidateRect(GetDlgItem(hwnd,DLG_COLOUR),NULL,FALSE);
00433           break;
00434         case IDCANCEL:
00435           EndDialog(hwnd,FALSE);
00436           return(TRUE);
00437         case IDOK:
00438           if(GetDlgItemText(hwnd,DLG_XSCALE,str,10) == 0)
00439              EndDialog(hwnd,FALSE);
00440           if((x=atof(str)) == 0)EndDialog(hwnd,FALSE);
00441           if(GetDlgItemText(hwnd,DLG_YSCALE,str,10) == 0)
00442              EndDialog(hwnd,FALSE);
00443           if((y=atof(str)) == 0)EndDialog(hwnd,FALSE);
00444           if(GetDlgItemText(hwnd,DLG_ZSCALE,str,10) == 0)
00445              EndDialog(hwnd,FALSE);
00446           if((z=atof(str)) == 0)EndDialog(hwnd,FALSE);
00447           EndDialog(hwnd,TRUE);
00448           return(TRUE);
00449         default:
00450           break;
00451       }
00452       break;
00453     default: break;
00454  }
00455  return FALSE;
00456 }
Generated on Tue Jan 28 06:18:32 2014 for OpenFX by  doxygen 1.6.3