Windows NT 4.0 source code leak
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.

621 lines
15 KiB

5 years ago
  1. #include <nt.h>
  2. #include <ntrtl.h>
  3. #include <nturtl.h>
  4. #include <windows.h>
  5. #include <commdlg.h>
  6. #include <ptypes32.h>
  7. #include <pwin32.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <memory.h>
  11. #include <math.h>
  12. #include <sys\types.h>
  13. #include <sys\timeb.h>
  14. #include <GL/glaux.h>
  15. #include "tk.h"
  16. #include "sscommon.h"
  17. #include "trackbal.h"
  18. static void Draw(void);
  19. static void DrawAuto(void);
  20. static void Init(void);
  21. static void InitLighting(void);
  22. static void Reshape(int, int);
  23. static void SetModelView( void );
  24. static GLenum Key(int key, GLenum mask);
  25. static int GetStringExtent( char *string, POINTFLOAT *extent );
  26. static void CalcStringMetrics( char *string );
  27. static void Init(void);
  28. static void InitLighting(void);
  29. static void Reshape(int, int);
  30. static GLenum Key(int key, GLenum mask);
  31. VOID Arg( LPSTR );
  32. // Global variables
  33. GLuint dlFont, dpFont;
  34. GLint firstGlyph;
  35. GLint Width = 300, Height = 300;
  36. POINTFLOAT strSize;
  37. int strLen;
  38. GLfloat xRot = 0.0f, yRot = 0.0f, zRot = 0.0f;
  39. GLdouble zTrans = -200.0;
  40. GLfloat extrusion;
  41. GLenum doubleBuffer = GL_TRUE;
  42. GLenum bLighting = GL_TRUE;
  43. GLenum fontStyle = WGL_FONT_POLYGONS;
  44. LPGLYPHMETRICSFLOAT lpgmf;
  45. // output from tesselator always ccw
  46. GLenum orientation = GL_CCW;
  47. char *texFileName = 0;
  48. GLint matIndex = 1;
  49. BOOL bAutoRotate = TRUE;
  50. BOOL bCullBack = TRUE;
  51. BOOL bTwoSidedLighting = FALSE;
  52. BOOL bInitTexture = TRUE;
  53. BOOL bTexture = FALSE;
  54. BOOL bAntialias = FALSE;
  55. char singleChar[] = "A";
  56. char string[] = "OpenGL!";
  57. char *drawString = singleChar;
  58. #if defined( TIME )
  59. #undef TIME
  60. #endif
  61. typedef struct _timeb TIME;
  62. enum {
  63. TIMER_START = 0,
  64. TIMER_STOP,
  65. TIMER_TIMING,
  66. TIMER_RESET
  67. };
  68. static int gTimerStatus = TIMER_RESET;
  69. int WINAPI
  70. WinMain( HINSTANCE hInstance,
  71. HINSTANCE hPrevInstance,
  72. LPSTR lpCmdLine,
  73. int nCmdShow
  74. )
  75. {
  76. GLenum type;
  77. Arg( lpCmdLine );
  78. tkInitPosition( 0, 0, Width, Height );
  79. type = TK_DEPTH16;
  80. type |= TK_RGB;
  81. type |= (doubleBuffer) ? TK_DOUBLE : TK_SINGLE;
  82. tkInitDisplayMode(type);
  83. if (tkInitWindow("Fontal assault") == GL_FALSE) {
  84. tkQuit();
  85. }
  86. Init();
  87. tkExposeFunc( Reshape );
  88. tkReshapeFunc( Reshape );
  89. tkKeyDownFunc( Key );
  90. tkMouseDownFunc( trackball_MouseDown );
  91. tkMouseUpFunc( trackball_MouseUp );
  92. trackball_Init( Width, Height );
  93. if( bAutoRotate ) {
  94. tkIdleFunc( DrawAuto );
  95. tkDisplayFunc(0);
  96. } else {
  97. tkDisplayFunc(Draw);
  98. }
  99. tkExec();
  100. return 1;
  101. }
  102. static GLenum Key(int key, GLenum mask)
  103. {
  104. switch (key) {
  105. case TK_ESCAPE:
  106. tkQuit();
  107. case TK_LEFT:
  108. yRot -= 5;
  109. break;
  110. case TK_RIGHT:
  111. yRot += 5;
  112. break;
  113. case TK_UP:
  114. xRot -= 5;
  115. break;
  116. case TK_DOWN:
  117. xRot += 5;
  118. break;
  119. case TK_X:
  120. zRot += 5;
  121. break;
  122. case TK_x:
  123. zRot -= 5;
  124. break;
  125. case TK_Z:
  126. zTrans -= strSize.y/10.0;
  127. SetModelView();
  128. break;
  129. case TK_z:
  130. zTrans += strSize.y/10.0;
  131. SetModelView();
  132. break;
  133. case TK_l:
  134. if( bLighting = !bLighting ) {
  135. glEnable(GL_LIGHTING);
  136. glEnable(GL_LIGHT0);
  137. }
  138. else
  139. {
  140. glDisable(GL_LIGHTING);
  141. glDisable(GL_LIGHT0);
  142. }
  143. break;
  144. case TK_m:
  145. if( !bTexture ) {
  146. if( ++matIndex > NUM_TEA_MATERIALS )
  147. matIndex =0;
  148. ss_SetMaterialIndex( matIndex );
  149. }
  150. break;
  151. case TK_n:
  152. singleChar[0] += 1;
  153. break;
  154. case TK_N:
  155. singleChar[0] -= 1;
  156. break;
  157. #if 1
  158. case TK_o:
  159. orientation = (orientation == GL_CCW) ? GL_CW : GL_CCW;
  160. glFrontFace( orientation );
  161. break;
  162. #else
  163. case TK_o:
  164. if( bAntialias = !bAntialias ) {
  165. if( fontStyle == WGL_FONT_LINES ) {
  166. glEnable( GL_LINE_SMOOTH );
  167. glEnable( GL_BLEND );
  168. } else {
  169. glDisable( GL_DEPTH_TEST );
  170. glEnable( GL_POLYGON_SMOOTH );
  171. glEnable( GL_BLEND );
  172. }
  173. } else {
  174. glDisable( GL_POLYGON_SMOOTH );
  175. glDisable( GL_LINE_SMOOTH );
  176. glDisable( GL_BLEND );
  177. glEnable( GL_DEPTH_TEST );
  178. }
  179. break;
  180. #endif
  181. case TK_t:
  182. bTexture = !bTexture;
  183. if( bTexture ) {
  184. ss_SetMaterialIndex( WHITE );
  185. glEnable( GL_TEXTURE_2D );
  186. glEnable(GL_TEXTURE_GEN_S);
  187. glEnable(GL_TEXTURE_GEN_T);
  188. } else {
  189. ss_SetMaterialIndex( matIndex );
  190. glDisable( GL_TEXTURE_2D );
  191. glDisable(GL_TEXTURE_GEN_S);
  192. glDisable(GL_TEXTURE_GEN_T);
  193. }
  194. break;
  195. case TK_s:
  196. // switch between wireframe and solid polygons
  197. fontStyle = (fontStyle == WGL_FONT_LINES) ? WGL_FONT_POLYGONS :
  198. WGL_FONT_LINES;
  199. break;
  200. case TK_c:
  201. drawString = (drawString == singleChar) ? string : singleChar;
  202. CalcStringMetrics( drawString );
  203. // change viewing matrix based on string extent
  204. Reshape( Width, Height );
  205. //SetModelView();
  206. break;
  207. case TK_u:
  208. // cUllface stuff
  209. bCullBack = !bCullBack;
  210. if( bCullBack ) {
  211. glCullFace( GL_BACK );
  212. glEnable( GL_CULL_FACE );
  213. } else {
  214. glDisable( GL_CULL_FACE );
  215. }
  216. break;
  217. case TK_2:
  218. bTwoSidedLighting = !bTwoSidedLighting;
  219. if( bTwoSidedLighting ) {
  220. glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, 1 );
  221. } else {
  222. glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, 0 );
  223. }
  224. break;
  225. case TK_a:
  226. // animate or not
  227. bAutoRotate= !bAutoRotate;
  228. if( bAutoRotate ) {
  229. tkIdleFunc(DrawAuto);
  230. tkDisplayFunc(0);
  231. } else {
  232. tkIdleFunc(0);
  233. tkDisplayFunc(Draw);
  234. }
  235. break;
  236. case TK_f :
  237. switch( gTimerStatus ) {
  238. case TIMER_START:
  239. break;
  240. case TIMER_STOP:
  241. case TIMER_RESET:
  242. gTimerStatus = TIMER_START;
  243. break;
  244. case TIMER_TIMING:
  245. gTimerStatus = TIMER_STOP;
  246. break;
  247. default:
  248. break;
  249. }
  250. break;
  251. default:
  252. return GL_FALSE;
  253. }
  254. return GL_TRUE;
  255. }
  256. static void InitLighting(void)
  257. {
  258. static float ambient[] = {0.1f, 0.1f, 0.1f, 1.0f};
  259. static float diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};
  260. static float position[] = {0.0f, 0.0f, 150.0f, 0.0f};
  261. static float back_mat_shininess[] = {50.0f};
  262. static float back_mat_specular[] = {0.5f, 0.5f, 0.2f, 1.0f};
  263. static float back_mat_diffuse[] = {1.0f, 0.0f, 0.0f, 1.0f};
  264. static float lmodel_ambient[] = {1.0f, 1.0f, 1.0f, 1.0f};
  265. static float decal[] = {(GLfloat) GL_DECAL};
  266. static float modulate[] = {(GLfloat) GL_MODULATE};
  267. static float repeat[] = {(GLfloat) GL_REPEAT};
  268. static float nearest[] = {(GLfloat) GL_NEAREST};
  269. TK_RGBImageRec *image;
  270. glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
  271. glDepthFunc(GL_LEQUAL);
  272. glEnable(GL_DEPTH_TEST);
  273. glFrontFace( orientation );
  274. glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
  275. glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
  276. glLightfv(GL_LIGHT0, GL_POSITION, position);
  277. glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
  278. if( bLighting ) {
  279. glEnable(GL_LIGHTING);
  280. glEnable(GL_LIGHT0);
  281. }
  282. // override back material
  283. glMaterialfv( GL_BACK, GL_AMBIENT, ambient );
  284. glMaterialfv( GL_BACK, GL_DIFFUSE, back_mat_diffuse );
  285. glMaterialfv( GL_BACK, GL_SPECULAR, back_mat_specular );
  286. glMaterialfv( GL_BACK, GL_SHININESS, back_mat_shininess );
  287. if( bTwoSidedLighting ) {
  288. glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, 1 );
  289. } else {
  290. glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, 0 );
  291. }
  292. // set back face culling mode
  293. if( bCullBack ) {
  294. glCullFace( GL_BACK );
  295. glEnable( GL_CULL_FACE );
  296. } else {
  297. glDisable( GL_CULL_FACE );
  298. }
  299. // Initialize materials from screen saver common lib
  300. ss_InitMaterials();
  301. matIndex = JADE;
  302. ss_SetMaterialIndex( matIndex );
  303. // do texturing preparations
  304. if( bInitTexture ) {
  305. //glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, decal);
  306. glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, modulate);
  307. glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, repeat);
  308. glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, repeat);
  309. glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, nearest);
  310. glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, nearest);
  311. if (texFileName) {
  312. image = tkRGBImageLoad(texFileName);
  313. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  314. gluBuild2DMipmaps(GL_TEXTURE_2D, 3, image->sizeX, image->sizeY,
  315. GL_RGB, GL_UNSIGNED_BYTE, image->data);
  316. }
  317. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
  318. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
  319. if( bTexture ) {
  320. glEnable( GL_TEXTURE_2D );
  321. glEnable(GL_TEXTURE_GEN_S);
  322. glEnable(GL_TEXTURE_GEN_T);
  323. ss_SetMaterialIndex( WHITE );
  324. }
  325. }
  326. }
  327. void Init(void)
  328. {
  329. CHOOSEFONT cf;
  330. LOGFONT lf;
  331. HFONT hfont, hfontOld;
  332. GLfloat chordal_deviation;
  333. int numGlyphs=224;
  334. HWND hwnd;
  335. HDC hdc;
  336. TIME baseTime;
  337. TIME thisTime;
  338. double elapsed;
  339. char buf[100];
  340. hdc = tkGetHDC();
  341. hwnd = tkGetHWND();
  342. // Create and select a font.
  343. cf.lStructSize = sizeof(CHOOSEFONT);
  344. cf.hwndOwner = hwnd;
  345. cf.hDC = hdc;
  346. cf.lpLogFont = &lf;
  347. cf.Flags = CF_SCREENFONTS | CF_INITTOLOGFONTSTRUCT | CF_TTONLY;
  348. memset(&lf, 0, sizeof(LOGFONT));
  349. lstrcpy(lf.lfFaceName, "Arial");
  350. lf.lfHeight = 50;
  351. ChooseFont(&cf);
  352. // lf reflects user's final choices
  353. hfont = CreateFontIndirect(&lf);
  354. hfontOld = SelectObject(hdc, hfont);
  355. // Generate a display list for font
  356. dlFont = glGenLists(numGlyphs);
  357. dpFont = glGenLists(numGlyphs);
  358. chordal_deviation = 0.005f;
  359. extrusion = 0.25f;
  360. firstGlyph = 32;
  361. lpgmf = (LPGLYPHMETRICSFLOAT) LocalAlloc( LMEM_FIXED, numGlyphs *
  362. sizeof(GLYPHMETRICSFLOAT) );
  363. wglUseFontOutlinesA(hdc, firstGlyph, numGlyphs, dlFont, chordal_deviation,
  364. extrusion, WGL_FONT_LINES, lpgmf );
  365. _ftime( &baseTime );
  366. wglUseFontOutlinesA(hdc, firstGlyph, numGlyphs, dpFont, chordal_deviation,
  367. extrusion, WGL_FONT_POLYGONS, NULL );
  368. glFinish();
  369. _ftime( &thisTime );
  370. elapsed = thisTime.time + thisTime.millitm/1000.0 -
  371. (baseTime.time + baseTime.millitm/1000.0);
  372. sprintf( buf, "Setup time = %5.2f seconds", elapsed );
  373. SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)buf);
  374. CalcStringMetrics( drawString );
  375. /* Set the clear color */
  376. glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
  377. // Initialize lighting
  378. InitLighting();
  379. // Blend func for AA
  380. glBlendFunc( GL_SRC_ALPHA, GL_ONE );
  381. }
  382. static void Reshape( int width, int height )
  383. {
  384. static GLdouble zNear = 0.1, zFar = 1000.0, fovy = 90.0;
  385. float aspect;
  386. trackball_Resize( width, height );
  387. /* Set up the projection matrix */
  388. Width = width;
  389. Height = height;
  390. aspect = Height == 0 ? 1.0f : Width/(float)Height;
  391. glViewport(0, 0, Width, Height );
  392. glMatrixMode(GL_PROJECTION);
  393. glLoadIdentity();
  394. zFar = 10.0f * strSize.x;
  395. gluPerspective(fovy, aspect, zNear, zFar );
  396. glMatrixMode(GL_MODELVIEW);
  397. SetModelView();
  398. }
  399. static void SetModelView( void )
  400. {
  401. glLoadIdentity();
  402. #if 1
  403. glTranslated( 0, 0, zTrans );
  404. #else
  405. /* this has side effect of flipping around viewpoint when pass through
  406. origin
  407. */
  408. gluLookAt( 0, 0, -zTrans,
  409. 0, 0, 0,
  410. 0, 1, 0 );
  411. #endif
  412. }
  413. void CalcFrameRate( char *buf, struct _timeb baseTime, int frameCount ) {
  414. static struct _timeb thisTime;
  415. double elapsed, frameRate;
  416. _ftime( &thisTime );
  417. elapsed = thisTime.time + thisTime.millitm/1000.0 -
  418. (baseTime.time + baseTime.millitm/1000.0);
  419. if( elapsed == 0.0 )
  420. sprintf( buf, "Frame rate = unknown" );
  421. else {
  422. frameRate = frameCount / elapsed;
  423. sprintf( buf, "Frame rate = %4.1f fps", frameRate );
  424. }
  425. }
  426. static void DrawAuto(void)
  427. {
  428. POINT pt;
  429. float matRot[4][4];
  430. static int frameCount = 0;
  431. static struct _timeb baseTime;
  432. char buf[1024];
  433. HWND hwnd;
  434. BOOL bTiming = TRUE;
  435. glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  436. if( fontStyle == WGL_FONT_LINES )
  437. glListBase(dlFont-32);
  438. else
  439. glListBase(dpFont-32);
  440. glPushMatrix();
  441. trackball_CalcRotMatrix( matRot );
  442. glMultMatrixf(&(matRot[0][0]));
  443. // now draw text, centered in window
  444. glTranslated( -strSize.x/2.0, -strSize.y/2.0, extrusion/2.0 );
  445. glCallLists(strLen, GL_UNSIGNED_BYTE, (GLubyte *) drawString);
  446. glPopMatrix();
  447. glFlush();
  448. if( doubleBuffer )
  449. tkSwapBuffers();
  450. hwnd = tkGetHWND();
  451. switch( gTimerStatus ) {
  452. case TIMER_START:
  453. gTimerStatus = TIMER_TIMING;
  454. frameCount = 0;
  455. sprintf( buf, "Timing..." );
  456. SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)buf);
  457. _ftime( &baseTime );
  458. break;
  459. case TIMER_STOP:
  460. gTimerStatus = TIMER_RESET;
  461. frameCount++;
  462. CalcFrameRate( buf, baseTime, frameCount );
  463. SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)buf);
  464. break;
  465. case TIMER_TIMING:
  466. frameCount++;
  467. break;
  468. case TIMER_RESET:
  469. default:
  470. break;
  471. }
  472. }
  473. static void Draw(void)
  474. {
  475. glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  476. if( fontStyle == WGL_FONT_LINES )
  477. glListBase(dlFont-32);
  478. else
  479. glListBase(dpFont-32);
  480. glPushMatrix();
  481. glRotatef( xRot, 1.0f, 0.0f, 0.0f );
  482. glRotatef( yRot, 0.0f, 1.0f, 0.0f );
  483. glRotatef( zRot, 0.0f, 0.0f, 1.0f );
  484. // center the string in window
  485. glTranslated( -strSize.x/2.0, -strSize.y/2.0, extrusion/2.0 );
  486. glCallLists(strLen, GL_UNSIGNED_BYTE, (GLubyte *) drawString);
  487. glPopMatrix();
  488. glFlush();
  489. if( doubleBuffer )
  490. tkSwapBuffers();
  491. }
  492. static int GetStringExtent( char *string, POINTFLOAT *extent )
  493. {
  494. int len, strLen;
  495. unsigned char *c;
  496. GLYPHMETRICSFLOAT *pgmf;
  497. extent->x = extent->y = 0.0f;
  498. len = strLen = lstrlenA( string );
  499. c = string;
  500. for( ; strLen; strLen--, c++ ) {
  501. if( *c < firstGlyph )
  502. continue;
  503. pgmf = &lpgmf[ *c - firstGlyph ];
  504. extent->x += pgmf->gmfCellIncX;
  505. if( pgmf->gmfBlackBoxY > extent->y )
  506. extent->y = pgmf->gmfBlackBoxY;
  507. }
  508. return len;
  509. }
  510. static void CalcStringMetrics( char *string )
  511. {
  512. // get string size for window reshape
  513. strLen = GetStringExtent( string, &strSize );
  514. // set zTrans based on glyph extent
  515. zTrans = - 3.0 * (strSize.y / 2.0f);
  516. }
  517. VOID Arg(LPSTR lpstr)
  518. {
  519. while (*lpstr && *lpstr != '-') lpstr++;
  520. // only one arg for now (e.g.: -f 3.rgb)
  521. lpstr++;
  522. if( *lpstr++ == 'f' ) {
  523. texFileName = ++lpstr;
  524. }
  525. }