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
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;
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(
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)
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)
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)
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;
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){
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,
00365 HWND hWnd,
00366 X__MEMORY_MANAGER *lpEVI
00367 ){
00368 char szbuf[255],*Op1;
00369 if(Op != NULL){
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);
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 }