00001
00002
00003
00004
00005
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"
00031 #include "..\animate\memdef.h"
00032 #include "defines.h"
00033 #include "rstruct.h"
00034 #include "honey.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
00058 #if __WATCOMC__
00059 int APIENTRY LibMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00060 #else
00061 BOOL WINAPI DllMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00062 #endif
00063 HANDLE ghMod;
00064 switch (dwReason) {
00065 case DLL_PROCESS_ATTACH:
00066 #if __X__MIPS__
00067 if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00068 #endif
00069 hDLLinstance = hDLL;
00070 break;
00071 case DLL_PROCESS_DETACH:
00072 #if __X__MIPS__
00073 if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00074 #endif
00075 break;
00076 }
00077 return (int)TRUE;
00078 }
00079
00080 #if __SC__
00081 #pragma startaddress(DllMain)
00082 #endif
00083
00084 static int type=0;
00085 static double thickness=0.05,inner=0.1,slope=0.4;
00086 static double c1[3]={0.0,0.0,0.0};
00087 static double x=1.0,y=1.0,z=1.0;
00088
00089 #if 0
00090 long CALLBACK ExternalTextureStartup(
00091 #else
00092 long _ExternalTextureStartup(
00093 #endif
00094 long frame,long nframes,char *parameter_list, X__SHADER *lpEVI
00095 ){
00096 if(parameter_list[0] != '#'){
00097 MessageBox ( GetFocus(),
00098 (LPCTSTR) "External texture: Startup",
00099 (LPCTSTR) "Parameter list missing",
00100 MB_OK | MB_SYSTEMMODAL );
00101 }
00102 else {
00103 parameter_list++;
00104 sscanf(parameter_list,"%f %f %f %f %f %f %ld %f %f %f",
00105 &x,&y,&z,&thickness,&inner,&slope,&type,
00106 &c1[0],&c1[1],&c1[2]);
00107 }
00108 return LoadAndCompileShader("honey");
00109 }
00110
00111 #if 0
00112 long CALLBACK ExternalTextureMorph(
00113 #else
00114 long _ExternalTextureMorph(
00115 #endif
00116 char *parameter_list, double mr){
00117 int i;
00118 long type_m;
00119 double thickness_m,inner_m,slope_m;
00120 double c1_m[3];
00121 double x_m,y_m,z_m;
00122 parameter_list++;
00123 sscanf(parameter_list,"%f %f %f %f %f %f %ld %f %f %f",
00124 &x_m,&y_m,&z_m,&thickness_m,&inner_m,&slope_m,&type_m,
00125 &c1_m[0],&c1_m[1],&c1_m[2]);
00126 for(i=0;i<3;i++)c1[i]=c1_m[i]+(c1[i]-c1_m[i])*mr;
00127 thickness=thickness_m+(thickness-thickness_m)*mr;
00128 inner=inner_m+(inner-inner_m)*mr;
00129 x=x_m+(x-x_m)*mr;
00130 y=y_m+(y-y_m)*mr;
00131 z=z_m+(z-z_m)*mr;
00132 return 1;
00133 }
00134
00135 #if 0
00136 long CALLBACK ExternalTextureProcedure(
00137 #else
00138 long _ExternalTextureProcedure(
00139 #endif
00140 long coord_type, vector p, vector n,
00141 double alpha, double beta, double gamma,
00142 double bump, double map_x, double map_y,
00143 double *alpha_channel, unsigned char sc[3], double colour[3],
00144 double *reflectivity, double *transparency,
00145 X__SHADER *lpEVI
00146 ){
00147 static
00148 vector pp[35]={{0.25,0.0, 0.0},
00149 {0.75,0.0, 0.0},
00150 {0.0, ROOT32/2, 0.0},
00151 {0.5, ROOT32/2, 0.0},
00152 {1.0, ROOT32/2, 0.0},
00153 {0.25,ROOT32, 0.0},
00154 {0.75,ROOT32, 0.0},
00155
00156 {-0.25,0.0, 0.0},
00157 { 1.25,0.0, 0.0},
00158 {-0.25,ROOT32, 0.0},
00159 { 1.25,ROOT32, 0.0},
00160 {-0.25,0.0, ROOT32},
00161 { 1.25,0.0, ROOT32},
00162 {-0.25,ROOT32, ROOT32},
00163 { 1.25,ROOT32, ROOT32},
00164 {-0.25,1.0/2.0/ROOT3,ROOT32/2.0},
00165 { 1.75,1.0/2.0/ROOT3,ROOT32/2.0},
00166 {0.0,1.0/2.0/ROOT3+ROOT32,ROOT32/2.0},
00167 {0.5,1.0/2.0/ROOT3+ROOT32,ROOT32/2.0},
00168 {1.0,1.0/2.0/ROOT3+ROOT32,ROOT32/2.0},
00169
00170 {0.0, 1.0/2.0/ROOT3-ROOT32/2,ROOT32/2.0},
00171 {0.5, 1.0/2.0/ROOT3-ROOT32/2,ROOT32/2.0},
00172 {1.0, 1.0/2.0/ROOT3-ROOT32/2,ROOT32/2.0},
00173 {0.25,1.0/2.0/ROOT3, ROOT32/2.0},
00174 {0.75,1.0/2.0/ROOT3, ROOT32/2.0},
00175 {0.0, 1.0/2.0/ROOT3+ROOT32/2,ROOT32/2.0},
00176 {0.5, 1.0/2.0/ROOT3+ROOT32/2,ROOT32/2.0},
00177 {1.0, 1.0/2.0/ROOT3+ROOT32/2,ROOT32/2.0},
00178 {0.25,0.0, ROOT32},
00179 {0.75,0.0, ROOT32},
00180 {0.0, ROOT32/2, ROOT32},
00181 {0.5, ROOT32/2, ROOT32},
00182 {1.0, ROOT32/2, ROOT32},
00183 {0.25,ROOT32, ROOT32},
00184 {0.75,ROOT32, ROOT32}};
00185 double dpoint[35];
00186 long i;
00187 double a,cc,xx,yy,zz,noiseH,r,g,b;
00188 vector u,v;
00189 vector dn,vt;
00190 double dx,dy,dz,zb,ccc,dc,zbb;
00191 BOOL ins;
00192 int id;
00193 cc=0.85;
00194
00195 xx=alpha / x;
00196 yy=beta / y;
00197 zz=gamma / z;
00198 yy /= ROOT32;
00199 xx=FMOD(xx,1.0);
00200 yy=FMOD(yy,ROOT32);
00201 zz /= ROOT32;
00202 zz=FMOD(zz,ROOT32);
00203 zb=-10.0;
00204 VECCOPY(n,dn)
00205 r=colour[0]/255.0;
00206 g=colour[1]/255.0;
00207 b=colour[2]/255.0;
00208 ins=TRUE;
00209 for(i=0;i<35;i++){
00210 dpoint[i] = -1.0;
00211 dx=(xx-pp[i][0]);
00212 dy=(yy-pp[i][1]);
00213 dz=(zz-pp[i][2]);
00214 if(fabs(dx) > cc)continue;
00215 if(fabs(dy) > cc)continue;
00216 if(fabs(dz) > cc)continue;
00217 if((a=sqrt(dx*dx+dy*dy+dz*dz)) < cc){
00218 dpoint[i]=a;
00219 dc=(cc-a);
00220 if(dc > zb){
00221 id=i;
00222 zb=dc;
00223 }
00224 }
00225 }
00226 zbb= -10.0;
00227 for(i=0;i<35;i++){
00228 if(i == id)continue;
00229 if(dpoint[i] >= 0.0){
00230 dc=(cc-dpoint[i]);
00231 if(dc > zbb){
00232 zbb=dc;
00233 }
00234 }
00235 }
00236 if((ccc=fabs(zbb - zb)) < thickness)ins=FALSE;
00237 if(ins && ccc < inner){
00238 v[0]=(xx-pp[id][0]);
00239 v[1]=(yy-pp[id][1]);
00240 v[2]=(zz-pp[id][2]);
00241 VECCOPY(dn,n)
00242 normalize(v);
00243 VECSCALE(v[0],tAxis_unorm,vt)
00244 VECSUM(v[1]*tAxis_vnorm,vt,vt)
00245 VECSUM(-v[2]*tAxis_n,vt,vt)
00246 normalize(vt);
00247 VECCOPY( vt,v)
00248 CROSS(v,n,u)
00249 CROSS(n,u,v)
00250 normalize(v);
00251 a=slope;
00252 if(type == 0)VECSUM(-a*v,(1.0-a)*n,n)
00253 else VECSUM(a*v,(1.0-a)*n,n)
00254 normalize(n);
00255 }
00256 if(!ins){
00257 r=c1[0]/255.0;
00258 g=c1[1]/255.0;
00259 b=c1[2]/255.0;
00260 }
00261 colour[0] = r * 255.0;
00262 colour[1] = g * 255.0;
00263 colour[2] = b * 255.0;
00264
00265
00266 return 1;
00267 }
00268 void _ExternalTextureClose(X__SHADER *lpEVI){
00269 UnloadCompiledShader(tGLshaderID);
00270 }
00271
00272 long _ExternalTextureProcedureGL(
00273 double bump_scale,
00274 unsigned char sc[3],
00275 unsigned char ac[3],
00276 X__SHADER *lpEVI
00277 ){
00278
00279 SetUniformVector(tGLshaderID,"MaterialC",(GLfloat)c1[0]/255.0,(GLfloat)c1[1]/255.0,(GLfloat)c1[2]/255.0);
00280 SetUniformInteger(tGLshaderID,"ShaderID",1);
00281 SetUniformVector(tGLshaderID,"ScalingV",1.0/x,1.0/z,1.0/y);
00282 SetUniformInteger(tGLshaderID,"Type",type);
00283 SetUniformVariable(tGLshaderID,"BumpSlope",slope/0.4);
00284 SetUniformVariable(tGLshaderID,"RidgeThickness",thickness);
00285 SetUniformVariable(tGLshaderID,"EdgeThickness",inner);
00286
00287
00288
00289
00290 DrawShadedPolygons(tmatpass,tpass,tprogID,tattrloc,tNface,tMainFp,tNvert,tMainVp);
00291 return 1;
00292 }
00294
00295 void CentreDialogOnScreen(HWND hwnd){
00296 RECT rcDlg;
00297 long Xres,Yres;
00298 Yres=GetSystemMetrics(SM_CYSCREEN);
00299 Xres=GetSystemMetrics(SM_CXSCREEN);
00300 GetWindowRect(hwnd,&rcDlg);
00301 OffsetRect(&rcDlg,-rcDlg.left,-rcDlg.top);
00302 OffsetRect(&rcDlg,(Xres-rcDlg.right)/2,(Yres-rcDlg.bottom)/2);
00303 SetWindowPos(hwnd,HWND_TOP,rcDlg.left,rcDlg.top,0,0,SWP_NOSIZE);
00304 return;
00305 }
00306
00307 static void SetColour(double *colour, HWND parent){
00308 CHOOSECOLOR cc;
00309 static COLORREF CustColours[16]={
00310 RGB(255,255,255), RGB(239,239,239), RGB(223,223,223), RGB(207,207,207),
00311 RGB(191,191,191), RGB(175,175,175), RGB(159,159,159), RGB(143,143,143),
00312 RGB(127,127,127), RGB(111,111,111), RGB( 95, 95, 95), RGB( 79, 79, 79),
00313 RGB( 63, 63, 63), RGB( 47, 47, 47), RGB( 31, 31, 31), RGB( 15, 15, 15) };
00314 cc.lStructSize=sizeof(CHOOSECOLOR);
00315 cc.hwndOwner=parent;
00316 cc.rgbResult=RGB((BYTE)colour[0],(BYTE)colour[1],(BYTE)colour[2]);
00317 cc.lpCustColors=(LPDWORD)CustColours;
00318 cc.Flags= CC_RGBINIT;
00319 cc.lCustData=(DWORD)0;
00320 if(ChooseColor(&cc)){
00321 colour[0]=(double)GetRValue(cc.rgbResult);
00322 colour[1]=(double)GetGValue(cc.rgbResult);
00323 colour[2]=(double)GetBValue(cc.rgbResult);
00324 }
00325 }
00326
00327 BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam);
00328
00329 #if 0
00330 char * CALLBACK SetExternalParameters(
00331 #else
00332 char * _SetExternalParameters(
00333 #endif
00334 char *Op,
00335 HWND hWnd,
00336 X__MEMORY_MANAGER *lpEVI
00337 ){
00338 char szbuf[255],*Op1;
00339 if(Op != NULL){
00340 Op1=Op;
00341 Op1++;
00342 sscanf(Op1,"%f %f %f %f %f %f %ld %f %f %f",
00343 &x,&y,&z,&thickness,&inner,&slope,&type,
00344 &c1[0],&c1[1],&c1[2]);
00345 }
00346 if(DialogBox(hDLLinstance,MAKEINTRESOURCE(DLG),hWnd,
00347 (DLGPROC)DlgProc) == FALSE)return Op;
00348 if(Op != NULL)CALL_FREE(Op);
00349 sprintf(szbuf,"# %.2f %.2f %.2f %.3f %.3f %.3f %ld "
00350 "%.2f %.2f %.2f ",
00351 x,y,z,thickness,inner,slope,type,
00352 c1[0],c1[1],c1[2]);
00353 if((Op=(char *)CALL_MALLOC(strlen(szbuf)+1)) == NULL){
00354 MessageBox (GetFocus(),"External shader: Out of memory","Error",
00355 MB_OK|MB_TASKMODAL|MB_ICONSTOP);
00356 return NULL;
00357 }
00358 strcpy(Op,szbuf);
00359 return Op;
00360 }
00361
00362 BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam){
00363 char str[16];
00364 switch( msg ) {
00365 case WM_INITDIALOG:
00366 sprintf(str,"%.2f",x);
00367 SendDlgItemMessage(hwnd,DLG_XSCALE,WM_SETTEXT,0,(LPARAM)str);
00368 SendDlgItemMessage(hwnd,DLG_XSCALE,EM_LIMITTEXT,(WPARAM)12,0);
00369 sprintf(str,"%.2f",y);
00370 SendDlgItemMessage(hwnd,DLG_YSCALE,WM_SETTEXT,0,(LPARAM)str);
00371 SendDlgItemMessage(hwnd,DLG_YSCALE,EM_LIMITTEXT,(WPARAM)12,0);
00372 sprintf(str,"%.2f",z);
00373 SendDlgItemMessage(hwnd,DLG_ZSCALE,WM_SETTEXT,0,(LPARAM)str);
00374 SendDlgItemMessage(hwnd,DLG_ZSCALE,EM_LIMITTEXT,(WPARAM)12,0);
00375 sprintf(str,"%.2f",thickness);
00376 SendDlgItemMessage(hwnd,DLG_THICKNESS,WM_SETTEXT,0,(LPARAM)str);
00377 SendDlgItemMessage(hwnd,DLG_THICKNESS,EM_LIMITTEXT,(WPARAM)12,0);
00378 sprintf(str,"%.2f",inner);
00379 SendDlgItemMessage(hwnd,DLG_INNER,WM_SETTEXT,0,(LPARAM)str);
00380 SendDlgItemMessage(hwnd,DLG_INNER,EM_LIMITTEXT,(WPARAM)12,0);
00381 sprintf(str,"%.2f",slope);
00382 SendDlgItemMessage(hwnd,DLG_SLOPE,WM_SETTEXT,0,(LPARAM)str);
00383 SendDlgItemMessage(hwnd,DLG_SLOPE,EM_LIMITTEXT,(WPARAM)12,0);
00384 if(type == 0)
00385 SendDlgItemMessage(hwnd,DLG_DIMPLE,BM_SETCHECK,TRUE,0);
00386 else if(type == 1)
00387 SendDlgItemMessage(hwnd,DLG_PIMPLE,BM_SETCHECK,TRUE,0);
00388
00389 CentreDialogOnScreen(hwnd);
00390 return TRUE;
00391 case WM_DRAWITEM:{
00392 LPDRAWITEMSTRUCT lpdis;
00393 HBRUSH hbr,hbrold;
00394 BYTE r,g,b;
00395 lpdis=(LPDRAWITEMSTRUCT)lparam;
00396 if(lpdis->CtlID == DLG_COLOUR1){
00397 if(lpdis->CtlID == DLG_COLOUR1){
00398 r=(BYTE)c1[0]; g=(BYTE)c1[1]; b=(BYTE)c1[2];
00399 }
00400 if(lpdis->itemState & ODS_SELECTED)
00401 InvertRect(lpdis->hDC,&(lpdis->rcItem));
00402 else{
00403 hbr=CreateSolidBrush(RGB(r,g,b));
00404 hbrold=SelectObject(lpdis->hDC,hbr);
00405 Rectangle(lpdis->hDC,lpdis->rcItem.left,lpdis->rcItem.top,
00406 lpdis->rcItem.right,lpdis->rcItem.bottom);
00407 SelectObject(lpdis->hDC,hbrold);
00408 DeleteObject(hbr);
00409 }
00410 }
00411 }
00412 break;
00413 case WM_COMMAND:
00414 switch(LOWORD(wparam)){
00415 case DLG_COLOUR1:
00416 SetColour(c1,hwnd);
00417 InvalidateRect(GetDlgItem(hwnd,DLG_COLOUR1),NULL,FALSE);
00418 break;
00419 case IDCANCEL:
00420 EndDialog(hwnd,FALSE);
00421 return(TRUE);
00422 case IDOK:
00423 if(GetDlgItemText(hwnd,DLG_THICKNESS,str,10) == 0)
00424 EndDialog(hwnd,FALSE);
00425 if((thickness=atof(str)) == 0)EndDialog(hwnd,FALSE);
00426 if(GetDlgItemText(hwnd,DLG_INNER,str,10) == 0)
00427 EndDialog(hwnd,FALSE);
00428 if((inner=atof(str)) == 0)EndDialog(hwnd,FALSE);
00429 if(GetDlgItemText(hwnd,DLG_SLOPE,str,10) == 0)
00430 EndDialog(hwnd,FALSE);
00431 if((slope=atof(str)) == 0)EndDialog(hwnd,FALSE);
00432 if(GetDlgItemText(hwnd,DLG_XSCALE,str,10) == 0)
00433 EndDialog(hwnd,FALSE);
00434 if((x=atof(str)) == 0)EndDialog(hwnd,FALSE);
00435 if(GetDlgItemText(hwnd,DLG_YSCALE,str,10) == 0)
00436 EndDialog(hwnd,FALSE);
00437 if((y=atof(str)) == 0)EndDialog(hwnd,FALSE);
00438 if(GetDlgItemText(hwnd,DLG_ZSCALE,str,10) == 0)
00439 EndDialog(hwnd,FALSE);
00440 if((z=atof(str)) == 0)EndDialog(hwnd,FALSE);
00441 if(SendDlgItemMessage(hwnd,DLG_DIMPLE,BM_GETCHECK,0,0))type=0;
00442 else type=1;
00443 EndDialog(hwnd,TRUE);
00444 return(TRUE);
00445 default:
00446 break;
00447 }
00448 break;
00449 default: break;
00450 }
00451 return FALSE;
00452 }