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.

479 lines
9.9 KiB

  1. /*
  2. * (c) Copyright 1993, Silicon Graphics, Inc.
  3. * ALL RIGHTS RESERVED
  4. * Permission to use, copy, modify, and distribute this software for
  5. * any purpose and without fee is hereby granted, provided that the above
  6. * copyright notice appear in all copies and that both the copyright notice
  7. * and this permission notice appear in supporting documentation, and that
  8. * the name of Silicon Graphics, Inc. not be used in advertising
  9. * or publicity pertaining to distribution of the software without specific,
  10. * written prior permission.
  11. *
  12. * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  13. * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  14. * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  15. * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
  16. * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  17. * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  18. * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  19. * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  20. * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN
  21. * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  22. * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  23. * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  24. *
  25. * US Government Users Restricted Rights
  26. * Use, duplication, or disclosure by the Government is subject to
  27. * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  28. * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  29. * clause at DFARS 252.227-7013 and/or in similar or successor
  30. * clauses in the FAR or the DOD or NASA FAR Supplement.
  31. * Unpublished-- rights reserved under the copyright laws of the
  32. * United States. Contractor/manufacturer is Silicon Graphics,
  33. * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.
  34. *
  35. * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  36. */
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. #include <math.h>
  40. #include <string.h>
  41. #include <time.h>
  42. #include "tk.h"
  43. #define MAXOBJS 10000
  44. #define MAXSELECT 100
  45. #define MAXFEED 300
  46. #define SOLID 1
  47. #define LINE 2
  48. #define POINT 3
  49. GLenum directRender;
  50. GLint windW, windH;
  51. GLuint selectBuf[MAXSELECT];
  52. GLfloat feedBuf[MAXFEED];
  53. GLint vp[4];
  54. float zRotation = 90.0;
  55. float zoom = 1.0;
  56. GLint objectCount;
  57. GLint numObjects;
  58. struct object {
  59. float v1[2];
  60. float v2[2];
  61. float v3[2];
  62. float color[3];
  63. } objects[MAXOBJS];
  64. GLenum linePoly = GL_FALSE;
  65. static void InitObjects(GLint num)
  66. {
  67. GLint i;
  68. float x, y;
  69. if (num > MAXOBJS) {
  70. num = MAXOBJS;
  71. }
  72. if (num < 1) {
  73. num = 1;
  74. }
  75. objectCount = num;
  76. srand((unsigned int)time(NULL));
  77. for (i = 0; i < num; i++) {
  78. x = (rand() % 300) - 150;
  79. y = (rand() % 300) - 150;
  80. objects[i].v1[0] = x + (rand() % 50) - 25;
  81. objects[i].v2[0] = x + (rand() % 50) - 25;
  82. objects[i].v3[0] = x + (rand() % 50) - 25;
  83. objects[i].v1[1] = y + (rand() % 50) - 25;
  84. objects[i].v2[1] = y + (rand() % 50) - 25;
  85. objects[i].v3[1] = y + (rand() % 50) - 25;
  86. objects[i].color[0] = ((rand() % 100) + 50) / 150.0;
  87. objects[i].color[1] = ((rand() % 100) + 50) / 150.0;
  88. objects[i].color[2] = ((rand() % 100) + 50) / 150.0;
  89. }
  90. }
  91. static void Init(void)
  92. {
  93. numObjects = 10;
  94. InitObjects(numObjects);
  95. glGetIntegerv(GL_VIEWPORT, vp);
  96. }
  97. static void Reshape(int width, int height)
  98. {
  99. windW = (GLint)width;
  100. windH = (GLint)height;
  101. }
  102. static void Render(GLenum mode)
  103. {
  104. GLint i;
  105. for (i = 0; i < objectCount; i++) {
  106. if (mode == GL_SELECT) {
  107. glLoadName(i);
  108. }
  109. glColor3fv(objects[i].color);
  110. glBegin(GL_POLYGON);
  111. glVertex2fv(objects[i].v1);
  112. glVertex2fv(objects[i].v2);
  113. glVertex2fv(objects[i].v3);
  114. glEnd();
  115. }
  116. }
  117. static GLint DoSelect(GLint x, GLint y)
  118. {
  119. GLint hits;
  120. glSelectBuffer(MAXSELECT, selectBuf);
  121. (void)glRenderMode(GL_SELECT);
  122. glInitNames();
  123. glPushName(~0);
  124. glPushMatrix();
  125. glViewport(0, 0, windW, windH);
  126. glGetIntegerv(GL_VIEWPORT, vp);
  127. glMatrixMode(GL_PROJECTION);
  128. glLoadIdentity();
  129. gluPickMatrix(x, windH-y, 4, 4, vp);
  130. gluOrtho2D(-175, 175, -175, 175);
  131. glMatrixMode(GL_MODELVIEW);
  132. glClearColor(0.0, 0.0, 0.0, 0.0);
  133. glClear(GL_COLOR_BUFFER_BIT);
  134. glScalef(zoom, zoom, zoom);
  135. glRotatef(zRotation, 0, 0, 1);
  136. Render(GL_SELECT);
  137. glPopMatrix();
  138. hits = glRenderMode(GL_RENDER);
  139. if (hits <= 0) {
  140. return -1;
  141. }
  142. return selectBuf[(hits-1)*4+3];
  143. }
  144. static void RecolorTri(GLint h)
  145. {
  146. objects[h].color[0] = ((rand() % 100) + 50) / 150.0;
  147. objects[h].color[1] = ((rand() % 100) + 50) / 150.0;
  148. objects[h].color[2] = ((rand() % 100) + 50) / 150.0;
  149. }
  150. static void DeleteTri(GLint h)
  151. {
  152. objects[h] = objects[objectCount-1];
  153. objectCount--;
  154. }
  155. static void GrowTri(GLint h)
  156. {
  157. float v[2];
  158. float *oldV;
  159. GLint i;
  160. v[0] = objects[h].v1[0] + objects[h].v2[0] + objects[h].v3[0];
  161. v[1] = objects[h].v1[1] + objects[h].v2[1] + objects[h].v3[1];
  162. v[0] /= 3;
  163. v[1] /= 3;
  164. for (i = 0; i < 3; i++) {
  165. switch (i) {
  166. case 0:
  167. oldV = objects[h].v1;
  168. break;
  169. case 1:
  170. oldV = objects[h].v2;
  171. break;
  172. case 2:
  173. oldV = objects[h].v3;
  174. break;
  175. }
  176. oldV[0] = 1.5 * (oldV[0] - v[0]) + v[0];
  177. oldV[1] = 1.5 * (oldV[1] - v[1]) + v[1];
  178. }
  179. }
  180. static GLenum Mouse(int mouseX, int mouseY, GLenum button)
  181. {
  182. GLint hit;
  183. hit = DoSelect((GLint)mouseX, (GLint)mouseY);
  184. if (hit != -1) {
  185. if (button & TK_LEFTBUTTON) {
  186. RecolorTri(hit);
  187. }
  188. if (button & TK_MIDDLEBUTTON) {
  189. GrowTri(hit);
  190. }
  191. if (button & TK_RIGHTBUTTON) {
  192. DeleteTri(hit);
  193. }
  194. return GL_TRUE;
  195. }
  196. return GL_FALSE;
  197. }
  198. static void Draw(void)
  199. {
  200. glPushMatrix();
  201. glViewport(0, 0, windW, windH);
  202. glGetIntegerv(GL_VIEWPORT, vp);
  203. glMatrixMode(GL_PROJECTION);
  204. glLoadIdentity();
  205. gluOrtho2D(-175, 175, -175, 175);
  206. glMatrixMode(GL_MODELVIEW);
  207. glClearColor(0.0, 0.0, 0.0, 0.0);
  208. glClear(GL_COLOR_BUFFER_BIT);
  209. glScalef(zoom, zoom, zoom);
  210. glRotatef(zRotation, 0, 0, 1);
  211. Render(GL_RENDER);
  212. glPopMatrix();
  213. glFlush();
  214. }
  215. static void DrawZoom(GLint x, GLint y)
  216. {
  217. glPushMatrix();
  218. glViewport(0, 0, windW, windH);
  219. glGetIntegerv(GL_VIEWPORT, vp);
  220. glMatrixMode(GL_PROJECTION);
  221. glLoadIdentity();
  222. gluPickMatrix(x, windH-y, 4, 4, vp);
  223. gluOrtho2D(-175, 175, -175, 175);
  224. glMatrixMode(GL_MODELVIEW);
  225. glClearColor(0.0, 0.0, 0.0, 0.0);
  226. glClear(GL_COLOR_BUFFER_BIT);
  227. glScalef(zoom, zoom, zoom);
  228. glRotatef(zRotation, 0, 0, 1);
  229. Render(GL_RENDER);
  230. glPopMatrix();
  231. }
  232. static void DumpFeedbackVert(GLint *i, GLint n)
  233. {
  234. GLint index;
  235. index = *i;
  236. if (index+7 > n) {
  237. *i = n;
  238. printf(" ???\n");
  239. return;
  240. }
  241. printf(" (%g %g %g), color = (%4.2f %4.2f %4.2f)\n",
  242. feedBuf[index],
  243. feedBuf[index+1],
  244. feedBuf[index+2],
  245. feedBuf[index+3],
  246. feedBuf[index+4],
  247. feedBuf[index+5]);
  248. index += 7;
  249. *i = index;
  250. }
  251. static void DrawFeedback(GLint n)
  252. {
  253. GLint i;
  254. GLint verts;
  255. printf("Feedback results (%d floats):\n", n);
  256. for (i = 0; i < n; i++) {
  257. switch ((GLint)feedBuf[i]) {
  258. case GL_POLYGON_TOKEN:
  259. printf("Polygon");
  260. i++;
  261. if (i < n) {
  262. verts = (GLint)feedBuf[i];
  263. i++;
  264. printf(": %d vertices", verts);
  265. } else {
  266. verts = 0;
  267. }
  268. printf("\n");
  269. while (verts) {
  270. DumpFeedbackVert(&i, n);
  271. verts--;
  272. }
  273. i--;
  274. break;
  275. case GL_LINE_TOKEN:
  276. printf("Line:\n");
  277. i++;
  278. DumpFeedbackVert(&i, n);
  279. DumpFeedbackVert(&i, n);
  280. i--;
  281. break;
  282. case GL_LINE_RESET_TOKEN:
  283. printf("Line Reset:\n");
  284. i++;
  285. DumpFeedbackVert(&i, n);
  286. DumpFeedbackVert(&i, n);
  287. i--;
  288. break;
  289. default:
  290. printf("%9.2f\n", feedBuf[i]);
  291. break;
  292. }
  293. }
  294. if (i == MAXFEED) {
  295. printf("...\n");
  296. }
  297. printf("\n");
  298. }
  299. static void DoFeedback(void)
  300. {
  301. GLint x;
  302. glFeedbackBuffer(MAXFEED, GL_3D_COLOR, feedBuf);
  303. (void)glRenderMode(GL_FEEDBACK);
  304. glPushMatrix();
  305. glViewport(0, 0, windW, windH);
  306. glGetIntegerv(GL_VIEWPORT, vp);
  307. glMatrixMode(GL_PROJECTION);
  308. glLoadIdentity();
  309. gluOrtho2D(-175, 175, -175, 175);
  310. glMatrixMode(GL_MODELVIEW);
  311. glClearColor(0.0, 0.0, 0.0, 0.0);
  312. glClear(GL_COLOR_BUFFER_BIT);
  313. glScalef(zoom, zoom, zoom);
  314. glRotatef(zRotation, 0, 0, 1);
  315. Render(GL_FEEDBACK);
  316. glPopMatrix();
  317. x = glRenderMode(GL_RENDER);
  318. if (x == -1) {
  319. x = MAXFEED;
  320. }
  321. DrawFeedback((GLint)x);
  322. }
  323. static GLenum Key(int key, GLenum mask)
  324. {
  325. int mouseX, mouseY;
  326. switch (key) {
  327. case TK_ESCAPE:
  328. tkQuit();
  329. case TK_LEFT:
  330. zRotation += 0.5;
  331. break;
  332. case TK_RIGHT:
  333. zRotation -= 0.5;
  334. break;
  335. case TK_Z:
  336. zoom /= 0.75;
  337. break;
  338. case TK_z:
  339. zoom *= 0.75;
  340. break;
  341. case TK_f:
  342. DoFeedback();
  343. break;
  344. case TK_d:
  345. tkGetMouseLoc(&mouseX, &mouseY);
  346. DrawZoom((GLint)mouseX, (GLint)mouseY);
  347. break;
  348. case TK_l:
  349. linePoly = !linePoly;
  350. if (linePoly) {
  351. glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  352. } else {
  353. glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  354. }
  355. break;
  356. default:
  357. return GL_FALSE;
  358. }
  359. return GL_TRUE;
  360. }
  361. static GLenum Args(int argc, char **argv)
  362. {
  363. GLint i;
  364. directRender = GL_FALSE;
  365. for (i = 1; i < argc; i++) {
  366. if (strcmp(argv[i], "-dr") == 0) {
  367. directRender = GL_TRUE;
  368. } else if (strcmp(argv[i], "-ir") == 0) {
  369. directRender = GL_FALSE;
  370. } else {
  371. printf("%s (Bad option).\n", argv[i]);
  372. return GL_FALSE;
  373. }
  374. }
  375. return GL_TRUE;
  376. }
  377. void main(int argc, char **argv)
  378. {
  379. GLenum type;
  380. if (Args(argc, argv) == GL_FALSE) {
  381. tkQuit();
  382. }
  383. windW = 300;
  384. windH = 300;
  385. tkInitPosition(0, 0, windW, windH);
  386. type = TK_RGB | TK_SINGLE;
  387. type |= (directRender) ? TK_DIRECT : TK_INDIRECT;
  388. tkInitDisplayMode(type);
  389. if (tkInitWindow("Select Test") == GL_FALSE) {
  390. tkQuit();
  391. }
  392. Init();
  393. tkExposeFunc(Reshape);
  394. tkReshapeFunc(Reshape);
  395. tkKeyDownFunc(Key);
  396. tkMouseDownFunc(Mouse);
  397. tkDisplayFunc(Draw);
  398. tkExec();
  399. }