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