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