Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

528 lines
14 KiB

  1. #include "viewer.h"
  2. #include "FileIO.h" // StreamSetFMode()
  3. #include "gmesh.h"
  4. #include "a3dstream.h"
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <ctype.h>
  8. #define GL_COLOR4(c) glColor4ub(((c)>>24)&0xff,((c)>>16)&0xff,((c)>>8)&0xff,((c)>>0)&0xff)
  9. /************************************************************************/
  10. /******************* Constants ******************************************/
  11. /************************************************************************/
  12. const int MAXOBJECT=250; // should be >= GLuint::MAXNUM
  13. const DWORD colorinvalid=0xffffff00;
  14. /************************************************************************/
  15. /******************* Globals ********************************************/
  16. /************************************************************************/
  17. static BOOL c_mat_set;
  18. BOOL pm_ready = FALSE;
  19. static int thickboundary = 2;
  20. static int thicksharp = 2;
  21. static int thicknormal = 1;
  22. static int thicka3d = 1;
  23. static BOOL perspec = TRUE;
  24. static int cullbackedges=1;
  25. static GLfloat ambient;
  26. static GLfloat backfacec[4];
  27. static float fdisplacepolygon = 1.0;
  28. static float sphereradius=.005;
  29. static float zoom = 1.0;
  30. static Frame tcam;
  31. static int nxpix,nypix; // window dimensions
  32. static float tzp1, tzp2;
  33. static float edgeoffset;
  34. static Frame tcami;
  35. static Point eyeinobframe;
  36. static int cob;
  37. static BOOL lcullface = FALSE;
  38. static BOOL haveconcave = FALSE;
  39. static DWORD edgecolor = 0x000000FF; // black
  40. static DWORD sharpedgecolor = 0xFF40FFFF; // bright yellow
  41. static float xpointerold, ypointerold;
  42. static DWORD curcol; // current color (for lines and points)
  43. static MatColor matcol; // material color (for polygons)
  44. static MatColor cuspcolor;
  45. static MatColor meshcolor;
  46. // default color for polygons
  47. const A3dVertexColor DEFAULTCOL(A3dColor(0.9, 0.6, 0.4),
  48. A3dColor(0.5, 0.5, 0.5),
  49. A3dColor(5, 0, 0));
  50. // default color for polylines and points
  51. const A3dVertexColor WHITECOL(A3dColor(1, 1, 1),
  52. A3dColor(0, 0, 0),
  53. A3dColor(1, 0, 0));
  54. static Array<DWORD> pm_ar_colors;
  55. PMesh *pmesh; // Global pointer to the (one and only) PM object
  56. PMeshRStream* pmrs=0;
  57. PMeshIter* pmi=0;
  58. float pm_lod_level = 0.0;
  59. float old_lod = 0.0;
  60. float curquat[4], lastquat[4];
  61. /************************************************************************/
  62. /******************* Function Prototypes ********************************/
  63. /************************************************************************/
  64. BOOL InitPMDrawState(void);
  65. BOOL read_pm (char *);
  66. void draw_pm (void);
  67. static void glinit(void);
  68. static int setupob(void);
  69. void pm_update_lod (void);
  70. /************************************************************************/
  71. /******************* Code ***********************************************/
  72. /************************************************************************/
  73. static DWORD packcolor(const A3dColor& col)
  74. {
  75. return (DWORD(col[0]*255.99)<<24)+(DWORD(col[1]*255.99)<<16)+
  76. (DWORD(col[2]*255.99)<<8)+(DWORD(255)<<0);
  77. }
  78. static void creatematcolor(const A3dVertexColor& vc, MatColor& col)
  79. {
  80. col.diffuse = packcolor(vc.d);
  81. col.specular = packcolor(vc.s);
  82. col.shininess = vc.g[0];
  83. }
  84. BOOL InitPMDrawState(char *fname)
  85. {
  86. perspec = TRUE;
  87. backfacec[0] = 0.15, backfacec[1]= 0.5, backfacec[2]= 0.15;
  88. backfacec[3] = 1.0;
  89. nxpix = g_wi.wSize.cx;
  90. nypix = g_wi.wSize.cy;
  91. float cuspcol[3]= {1.0, 0.2, 0.2};
  92. float meshcd[3]={0.8, 0.5, 0.4};
  93. float meshcs[3]={0.5, 0.5, 0.5};
  94. float meshcp[3]={5, 0, 0};
  95. int cuspbright = (cuspcol[0] + cuspcol[1] + cuspcol[2]>2.);
  96. A3dVertexColor CUSPCOL(A3dColor(cuspcol[0],cuspcol[1],cuspcol[2]),
  97. A3dColor(cuspcol[0],cuspcol[1],cuspcol[2]),
  98. A3dColor(cuspbright?1:7,0,0));
  99. creatematcolor(CUSPCOL, cuspcolor);
  100. creatematcolor(A3dVertexColor(A3dColor(meshcd[0],meshcd[1],meshcd[2]),
  101. A3dColor(meshcs[0],meshcs[1],meshcs[2]),
  102. A3dColor(meshcp[0],meshcp[1],meshcp[2])),
  103. meshcolor);
  104. if (fname)
  105. if (read_pm( fname ))
  106. {
  107. glinit();
  108. setupob ();
  109. return TRUE;
  110. }
  111. return FALSE;
  112. }
  113. static int pthick;
  114. static void resetthickness()
  115. {
  116. pthick=-1;
  117. }
  118. static void setthickness2(int vthick)
  119. {
  120. pthick=vthick;
  121. if (vthick > 1)
  122. glLineWidth((GLfloat)(vthick));
  123. }
  124. inline void InitViewing (void)
  125. {
  126. float a = 1.0f / min(nxpix, nypix);
  127. tzp1 = 0.5f / (zoom*nxpix*a);
  128. tzp2 = 0.5f / (zoom*nypix*a);
  129. //if (g_s.yon <= g_s.hither*1.0001) g_s.yon = g_s.hither*1.0001;
  130. glMatrixMode(GL_PROJECTION);
  131. glLoadIdentity();
  132. //Reshape (nxpix, nypix);
  133. #if 1
  134. if (perspec)
  135. {
  136. glFrustum (-nxpix*a*zoom*g_s.hither, nxpix*a*zoom*g_s.hither,
  137. -nypix*a*zoom*g_s.hither, nypix*a*zoom*g_s.hither,
  138. g_s.hither, g_s.yon);
  139. }
  140. else
  141. {
  142. glOrtho(-nxpix*a*zoom, nxpix*a*zoom,
  143. -nypix*a*zoom, nypix*a*zoom,
  144. g_s.hither, g_s.yon);
  145. }
  146. #endif
  147. glMatrixMode(GL_MODELVIEW);
  148. glLoadIdentity();
  149. trackball(curquat, 0.0, 0.0, 0.0, 0.0);
  150. }
  151. inline void setthickness(int vthick)
  152. {
  153. if (vthick!=pthick) setthickness2(vthick);
  154. }
  155. // must be followed by setupob()!
  156. static void glinit(void)
  157. {
  158. const float cedgeoffset=4.2e-3f;
  159. edgeoffset = cedgeoffset*zoom*fdisplacepolygon;
  160. InitViewing ();
  161. NEST
  162. { // front material
  163. float material[] = {0.0, 0.0, 0.0, 1.0};
  164. glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, material);
  165. }
  166. NEST
  167. { // back material
  168. float amb[] = {0.0, 0.0, 0.0, 1.0};
  169. float diff[] = {0.15, 0.15, 0.15, 1.0};
  170. glMaterialfv(GL_BACK, GL_AMBIENT, amb);
  171. glMaterialfv(GL_BACK, GL_DIFFUSE, diff);
  172. glMaterialfv(GL_BACK, GL_EMISSION, backfacec);
  173. }
  174. NEST
  175. { // lighting model
  176. GLfloat ambient[] = { 0.2, 0.2, 0.2, 1.0 };
  177. GLfloat diffuse[] = { 0.7, 0.7, 0.7, 1.0 };
  178. GLfloat position[] = { 0.0, 0.0, 2.0, 0.0 };
  179. glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
  180. glLightfv(GL_LIGHT0, GL_DIFFUSE, ambient);
  181. glLightfv(GL_LIGHT0, GL_POSITION, position);
  182. }
  183. resetthickness();
  184. setthickness(thicka3d);
  185. glDepthRange(0x0, 0x7FFFFF);
  186. c_mat_set = FALSE;
  187. glDisable (GL_COLOR_MATERIAL);
  188. curcol = colorinvalid;
  189. matcol.diffuse = colorinvalid;
  190. matcol.specular = colorinvalid;
  191. matcol.shininess = -1;
  192. }
  193. static int setupob(void)
  194. {
  195. char buf[200];
  196. NEST
  197. {
  198. GLfloat ambient[] = {0.25, 0.25, 0.25, 1.0};
  199. glLightModelfv (GL_LIGHT_MODEL_AMBIENT, ambient);
  200. glLightModeli (GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
  201. glLightModeli (GL_LIGHT_MODEL_TWO_SIDE, 0);
  202. }
  203. glFrontFace (front_face);
  204. glCullFace(cull_face);
  205. if (cull_enable)
  206. glEnable(GL_CULL_FACE);
  207. else
  208. glDisable(GL_CULL_FACE);
  209. glPolygonMode(GL_FRONT_AND_BACK, filled_mode?GL_FILL:GL_LINE);
  210. //if (edge_mode) displacepolygon(fdisplacepolygon);
  211. // Compute the model bounding box
  212. g_s.max_vert[0] = g_s.max_vert[1] = g_s.max_vert[2] = -1e30f;
  213. g_s.min_vert[0] = g_s.min_vert[1] = g_s.min_vert[2] = 1e30f;
  214. int nv0=pmesh->_base_mesh._vertices.num();
  215. //int nvsplits=pmesh->_vsplits.num();
  216. //int nv=nv0+int((nvsplits+1)*0.999999f); //max LOD
  217. pmi->goto_nvertices(nv0);
  218. const AWMesh& wmesh=*pmi;
  219. int num_v = wmesh._vertices.num();
  220. //S_Vertex* svp = wmesh._vertices;
  221. for (int i=0; i<num_v; i++)
  222. {
  223. #if 0
  224. const float* p1 = &wmesh._vertices[i].attrib.point[0];
  225. for (int j=0; j<3; j)
  226. {
  227. if (p1[j] > g_s.max_vert[j]) g_s.max_vert[j] = p1[j];
  228. if (p1[j] < g_s.min_vert[j]) g_s.min_vert[j] = p1[j];
  229. }
  230. #endif
  231. }
  232. sprintf (buf, "NumVert = %d\r\n", num_v);
  233. MessageBox (NULL, buf, "Info", MB_OK);
  234. //pmi->goto_nvertices(nv0);
  235. return 1;
  236. }
  237. static void updatecurcolor2(DWORD col)
  238. {
  239. if (c_mat_set) c_mat_set = 0, glDisable(GL_COLOR_MATERIAL);
  240. curcol = col;
  241. glColor4ub ( (col>>24) & 0xff,
  242. (col>>16) & 0xff,
  243. (col>>8) & 0xff,
  244. (col>>0) & 0xff);
  245. matcol.diffuse = colorinvalid;
  246. matcol.specular = colorinvalid;
  247. matcol.shininess = -1;
  248. }
  249. inline void updatecurcolor (DWORD col)
  250. {
  251. if (col != curcol) updatecurcolor2 (col);
  252. }
  253. static void updatematcolor2(const MatColor& col)
  254. {
  255. if (!c_mat_set)
  256. {
  257. c_mat_set = TRUE;
  258. glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
  259. }
  260. glEnable(GL_COLOR_MATERIAL);
  261. if (col.shininess != matcol.shininess)
  262. {
  263. matcol.shininess = col.shininess;
  264. glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, matcol.shininess);
  265. }
  266. if (col.specular != matcol.specular)
  267. {
  268. matcol.specular = col.specular;
  269. glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
  270. GL_COLOR4(matcol.specular);
  271. glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
  272. }
  273. if (col.diffuse != matcol.diffuse)
  274. {
  275. matcol.diffuse = col.diffuse;
  276. GL_COLOR4(col.diffuse);
  277. }
  278. curcol=colorinvalid;
  279. }
  280. inline void updatematcolor(const MatColor& col)
  281. {
  282. if (col.diffuse != matcol.diffuse ||
  283. col.specular != matcol.specular ||
  284. col.shininess != matcol.shininess)
  285. updatematcolor2(col);
  286. }
  287. inline void updatematdiffuse(DWORD cd)
  288. {
  289. if (cd != matcol.diffuse)
  290. {
  291. if (!c_mat_set)
  292. {
  293. c_mat_set = TRUE;
  294. glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
  295. }
  296. glEnable(GL_COLOR_MATERIAL);
  297. matcol.diffuse = cd;
  298. GL_COLOR4(cd);
  299. curcol=colorinvalid;
  300. }
  301. }
  302. inline void pm_draw_segment(int fn, int v0, int v1,
  303. const Point& p0, const Point& p1)
  304. {
  305. if (fn >= 0 && v0 > v1) return;
  306. glBegin(GL_LINES);
  307. glVertex3fv(&p0[0]);
  308. glVertex3fv(&p1[0]);
  309. glEnd();
  310. }
  311. void draw_pm (void)
  312. {
  313. updatematcolor(meshcolor);
  314. const AWMesh& wmesh=*pmi;
  315. if (!edge_mode || filled_mode)
  316. {
  317. const S_Vertex* svp = wmesh._vertices;
  318. const S_Wedge* swp = wmesh._wedges;
  319. const S_Face* sfp = wmesh._faces;
  320. const DWORD * matp = pm_ar_colors;
  321. ForIndex(f, wmesh._faces.num())
  322. {
  323. int matid = sfp[f].attrib.matid;
  324. updatematdiffuse(matp[matid]);
  325. glBegin(GL_TRIANGLES);
  326. const int* wp = sfp[f].wedges;
  327. int w0 = wp[0];
  328. int w1 = wp[1];
  329. int w2 = wp[2];
  330. int v0 = swp[w0].vertex;
  331. int v1 = swp[w1].vertex;
  332. int v2 = swp[w2].vertex;
  333. const float* n0 = &swp[w0].attrib.normal[0];
  334. const float* p0 = &svp[v0].attrib.point[0];
  335. const float* n1 = &swp[w1].attrib.normal[0];
  336. const float* p1 = &svp[v1].attrib.point[0];
  337. const float* n2=&swp[w2].attrib.normal[0];
  338. const float* p2=&svp[v2].attrib.point[0];
  339. glNormal3fv(n0); glVertex3fv(p0);
  340. glNormal3fv(n1); glVertex3fv(p1);
  341. glNormal3fv(n2); glVertex3fv(p2);
  342. glEnd();
  343. } EndFor;
  344. }
  345. if (edge_mode)
  346. {
  347. // Options cullbackedges, lquickmode not handled.
  348. setthickness (thicknormal);
  349. updatecurcolor (edgecolor);
  350. const S_Vertex* svp = wmesh._vertices;
  351. const S_Wedge* swp = wmesh._wedges;
  352. const S_Face* sfp = wmesh._faces;
  353. const S_FaceNeighbors* snp = wmesh._fnei;
  354. ForIndex(f, wmesh._faces.num())
  355. {
  356. const int* wp = sfp[f].wedges;
  357. const int* np = snp[f].faces;
  358. int w0 = wp[0];
  359. int w1 = wp[1];
  360. int v0 = swp[w0].vertex;
  361. int v1 = swp[w1].vertex;
  362. const Point& p0 = svp[v0].attrib.point;
  363. const Point& p1 = svp[v1].attrib.point;
  364. int fn2 = np[2];
  365. int fn0 = np[0];
  366. pm_draw_segment (fn2, v0, v1, p0, p1);
  367. int w2 = wp[2];
  368. int v2 = swp[w2].vertex;
  369. const Point& p2 = svp[v2].attrib.point;
  370. int fn1 = np[1];
  371. pm_draw_segment (fn0, v1, v2, p1, p2);
  372. pm_draw_segment (fn1, v2, v0, p2, p0);
  373. } EndFor;
  374. setthickness (thicka3d);
  375. }
  376. }
  377. #define ForStringKeyValue(S,KS,KL,VS,VL) \
  378. { StringKeyIter zz(S); \
  379. const char* KS; const char* VS; \
  380. int KL; int VL; \
  381. while (zz.next(KS,KL,VS,VL)) {
  382. const char* string_key(const char* str, const char* key)
  383. {
  384. int keyl=strlen(key);
  385. ForStringKeyValue(str,kb,kl,vb,vl) {
  386. int found=!strncmp(kb,key,kl) && kl==keyl;
  387. if (!found) continue;
  388. char* sret=(char*)hform(""); // un-const
  389. strncat(sret,vb,vl);
  390. return sret;
  391. } EndFor;
  392. return 0;
  393. }
  394. BOOL read_pm (char *fname)
  395. {
  396. BOOL retVal = TRUE;
  397. if (pmesh)
  398. delete pmesh;
  399. pmesh=new PMesh;
  400. {
  401. ifstream fi(fname);
  402. StreamSetFMode((fstream&)fi,1);
  403. pmesh->read(fi);
  404. }
  405. pmrs=new PMeshRStream(*pmesh);
  406. pmi=new PMeshIter(*pmrs);
  407. // When pmrs is created, it automatically reads in pmesh._base_mesh
  408. const AWMesh& base_mesh=pmesh->_base_mesh;
  409. const Materials& materials=base_mesh._materials;
  410. ForIndex(matid,materials.num()) {
  411. DWORD pcolor;
  412. const char* str=materials.get(matid);
  413. const char* s=string_key(str,"rgb");
  414. if (s)
  415. {
  416. A3dColor co;
  417. if (sscanf(s,"( %g %g %g )",&co[0],&co[1],&co[2])!=3)
  418. MessageBox (NULL, "viewer.cxx", "Error", MB_OK);
  419. //assertx(sscanf(s,"( %g %g %g )",&co[0],&co[1],&co[2])==3);
  420. pcolor=packcolor(co);
  421. }
  422. else
  423. {
  424. pcolor = meshcolor.diffuse;
  425. }
  426. pm_ar_colors+=pcolor;
  427. } EndFor;
  428. pm_lod_level = 0.0f;
  429. auxSetScrollPos (AUX_HSCROLL, auxGetScrollMin(AUX_HSCROLL));
  430. pm_ready = TRUE;
  431. return retVal;
  432. }
  433. void pm_update_lod (void)
  434. {
  435. //float flevel=min(pm_lod_level,1.f);
  436. int nv0=pmesh->_base_mesh._vertices.num();
  437. int nvsplits=pmesh->_vsplits.num();
  438. int nv=nv0+int((nvsplits+1)*pm_lod_level*.999999f);
  439. pmi->goto_nvertices(nv);
  440. }