00001
00002
00003
00004
00005
00006
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"
00032 #include "..\animate\memdef.h"
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;
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
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)
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)
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)
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
00273 if(a < 0.1){
00274 a=0.1;
00275 }
00276 else{
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,
00367 HWND hWnd,
00368 X__MEMORY_MANAGER *lpEVI
00369 ){
00370 char szbuf[255],*Op1;
00371 if(Op != NULL){
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);
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 }