Clone of mesa.
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028
  1. /* projtex.c - by David Yu and David Blythe, SGI */
  2. /**
  3. ** Demonstrates simple projective texture mapping.
  4. **
  5. ** Button1 changes view, Button2 moves texture.
  6. **
  7. ** (See: Segal, Korobkin, van Widenfelt, Foran, and Haeberli
  8. ** "Fast Shadows and Lighting Effects Using Texture Mapping", SIGGRAPH '92)
  9. **
  10. ** 1994,1995 -- David G Yu
  11. **
  12. ** cc -o projtex projtex.c texture.c -lglut -lGLU -lGL -lX11 -lm
  13. **/
  14. #include <assert.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <math.h>
  18. #include <GL/glut.h>
  19. #if 0
  20. #include "texture.h"
  21. #else
  22. #include "../util/readtex.c"
  23. #endif
  24. /* Some <math.h> files do not define M_PI... */
  25. #ifndef M_PI
  26. #define M_PI 3.14159265358979323846
  27. #endif
  28. #define MAX_TEX 4
  29. int NumTextures = 1;
  30. int winWidth, winHeight;
  31. GLboolean redrawContinuously = GL_FALSE;
  32. float angle, axis[3];
  33. enum MoveModes {
  34. MoveNone, MoveView, MoveObject, MoveTexture
  35. };
  36. enum MoveModes mode = MoveNone;
  37. GLfloat objectXform[4][4];
  38. GLfloat textureXform[MAX_TEX][4][4];
  39. void (*drawObject) (void);
  40. void (*loadTexture) (void);
  41. GLboolean textureEnabled = GL_TRUE;
  42. GLboolean showProjection = GL_TRUE;
  43. GLboolean linearFilter = GL_TRUE;
  44. char *texFilename[MAX_TEX] = {
  45. "../images/girl.rgb",
  46. "../images/tile.rgb",
  47. "../images/bw.rgb",
  48. "../images/reflect.rgb"
  49. };
  50. GLfloat zoomFactor = 1.0;
  51. /*****************************************************************/
  52. void ActiveTexture(int i)
  53. {
  54. glActiveTextureARB(i);
  55. }
  56. /* matrix = identity */
  57. void
  58. matrixIdentity(GLfloat matrix[16])
  59. {
  60. matrix[0] = 1.0;
  61. matrix[1] = 0.0;
  62. matrix[2] = 0.0;
  63. matrix[3] = 0.0;
  64. matrix[4] = 0.0;
  65. matrix[5] = 1.0;
  66. matrix[6] = 0.0;
  67. matrix[7] = 0.0;
  68. matrix[8] = 0.0;
  69. matrix[9] = 0.0;
  70. matrix[10] = 1.0;
  71. matrix[11] = 0.0;
  72. matrix[12] = 0.0;
  73. matrix[13] = 0.0;
  74. matrix[14] = 0.0;
  75. matrix[15] = 1.0;
  76. }
  77. /* matrix2 = transpose(matrix1) */
  78. void
  79. matrixTranspose(GLfloat matrix2[16], GLfloat matrix1[16])
  80. {
  81. matrix2[0] = matrix1[0];
  82. matrix2[1] = matrix1[4];
  83. matrix2[2] = matrix1[8];
  84. matrix2[3] = matrix1[12];
  85. matrix2[4] = matrix1[1];
  86. matrix2[5] = matrix1[5];
  87. matrix2[6] = matrix1[9];
  88. matrix2[7] = matrix1[13];
  89. matrix2[8] = matrix1[2];
  90. matrix2[9] = matrix1[6];
  91. matrix2[10] = matrix1[10];
  92. matrix2[11] = matrix1[14];
  93. matrix2[12] = matrix1[3];
  94. matrix2[13] = matrix1[7];
  95. matrix2[14] = matrix1[14];
  96. matrix2[15] = matrix1[15];
  97. }
  98. /*****************************************************************/
  99. /* load SGI .rgb image (pad with a border of the specified width and color) */
  100. #if 0
  101. static void
  102. imgLoad(char *filenameIn, int borderIn, GLfloat borderColorIn[4],
  103. int *wOut, int *hOut, GLubyte ** imgOut)
  104. {
  105. int border = borderIn;
  106. int width, height;
  107. int w, h;
  108. GLubyte *image, *img, *p;
  109. int i, j, components;
  110. image = (GLubyte *) read_texture(filenameIn, &width, &height, &components);
  111. w = width + 2 * border;
  112. h = height + 2 * border;
  113. img = (GLubyte *) calloc(w * h, 4 * sizeof(unsigned char));
  114. p = img;
  115. for (j = -border; j < height + border; ++j) {
  116. for (i = -border; i < width + border; ++i) {
  117. if (0 <= j && j <= height - 1 && 0 <= i && i <= width - 1) {
  118. p[0] = image[4 * (j * width + i) + 0];
  119. p[1] = image[4 * (j * width + i) + 1];
  120. p[2] = image[4 * (j * width + i) + 2];
  121. p[3] = 0xff;
  122. } else {
  123. p[0] = borderColorIn[0] * 0xff;
  124. p[1] = borderColorIn[1] * 0xff;
  125. p[2] = borderColorIn[2] * 0xff;
  126. p[3] = borderColorIn[3] * 0xff;
  127. }
  128. p += 4;
  129. }
  130. }
  131. free(image);
  132. *wOut = w;
  133. *hOut = h;
  134. *imgOut = img;
  135. }
  136. #endif
  137. /*****************************************************************/
  138. /* Load the image file specified on the command line as the current texture */
  139. void
  140. loadImageTextures(void)
  141. {
  142. GLfloat borderColor[4] =
  143. {1.0, 1.0, 1.0, 1.0};
  144. int tex;
  145. for (tex = 0; tex < NumTextures; tex++) {
  146. GLubyte *image, *texData3, *texData4;
  147. GLint imgWidth, imgHeight;
  148. GLenum imgFormat;
  149. int i, j;
  150. printf("loading %s\n", texFilename[tex]);
  151. image = LoadRGBImage(texFilename[tex], &imgWidth, &imgHeight, &imgFormat);
  152. if (!image) {
  153. printf("can't find %s\n", texFilename[tex]);
  154. exit(1);
  155. }
  156. assert(imgFormat == GL_RGB);
  157. /* scale to 256x256 */
  158. texData3 = malloc(256 * 256 * 4);
  159. texData4 = malloc(256 * 256 * 4);
  160. assert(texData3);
  161. assert(texData4);
  162. gluScaleImage(imgFormat, imgWidth, imgHeight, GL_UNSIGNED_BYTE, image,
  163. 256, 256, GL_UNSIGNED_BYTE, texData3);
  164. /* convert to rgba */
  165. for (i = 0; i < 256 * 256; i++) {
  166. texData4[i*4+0] = texData3[i*3+0];
  167. texData4[i*4+1] = texData3[i*3+1];
  168. texData4[i*4+2] = texData3[i*3+2];
  169. texData4[i*4+3] = 128;
  170. }
  171. /* put transparent border around image */
  172. for (i = 0; i < 256; i++) {
  173. texData4[i*4+0] = 255;
  174. texData4[i*4+1] = 255;
  175. texData4[i*4+2] = 255;
  176. texData4[i*4+3] = 0;
  177. }
  178. j = 256 * 255 * 4;
  179. for (i = 0; i < 256; i++) {
  180. texData4[j + i*4+0] = 255;
  181. texData4[j + i*4+1] = 255;
  182. texData4[j + i*4+2] = 255;
  183. texData4[j + i*4+3] = 0;
  184. }
  185. for (i = 0; i < 256; i++) {
  186. j = i * 256 * 4;
  187. texData4[j+0] = 255;
  188. texData4[j+1] = 255;
  189. texData4[j+2] = 255;
  190. texData4[j+3] = 0;
  191. }
  192. for (i = 0; i < 256; i++) {
  193. j = i * 256 * 4 + 255 * 4;
  194. texData4[j+0] = 255;
  195. texData4[j+1] = 255;
  196. texData4[j+2] = 255;
  197. texData4[j+3] = 0;
  198. }
  199. ActiveTexture(GL_TEXTURE0_ARB + tex);
  200. glBindTexture(GL_TEXTURE_2D, tex + 1);
  201. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  202. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0,
  203. GL_RGBA, GL_UNSIGNED_BYTE, texData4);
  204. if (linearFilter) {
  205. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  206. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  207. } else {
  208. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  209. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  210. }
  211. glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
  212. }
  213. }
  214. /* Create a simple spotlight pattern and make it the current texture */
  215. void
  216. loadSpotlightTexture(void)
  217. {
  218. static int texWidth = 64, texHeight = 64;
  219. static GLubyte *texData;
  220. GLfloat borderColor[4] =
  221. {0.1, 0.1, 0.1, 1.0};
  222. if (!texData) {
  223. GLubyte *p;
  224. int i, j;
  225. texData = (GLubyte *) malloc(texWidth * texHeight * 4 * sizeof(GLubyte));
  226. p = texData;
  227. for (j = 0; j < texHeight; ++j) {
  228. float dy = (texHeight * 0.5 - j + 0.5) / (texHeight * 0.5);
  229. for (i = 0; i < texWidth; ++i) {
  230. float dx = (texWidth * 0.5 - i + 0.5) / (texWidth * 0.5);
  231. float r = cos(M_PI / 2.0 * sqrt(dx * dx + dy * dy));
  232. float c;
  233. r = (r < 0) ? 0 : r * r;
  234. c = 0xff * (r + borderColor[0]);
  235. p[0] = (c <= 0xff) ? c : 0xff;
  236. c = 0xff * (r + borderColor[1]);
  237. p[1] = (c <= 0xff) ? c : 0xff;
  238. c = 0xff * (r + borderColor[2]);
  239. p[2] = (c <= 0xff) ? c : 0xff;
  240. c = 0xff * (r + borderColor[3]);
  241. p[3] = (c <= 0xff) ? c : 0xff;
  242. p += 4;
  243. }
  244. }
  245. }
  246. if (linearFilter) {
  247. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  248. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  249. } else {
  250. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  251. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  252. }
  253. glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
  254. gluBuild2DMipmaps(GL_TEXTURE_2D, 4, texWidth, texHeight,
  255. GL_RGBA, GL_UNSIGNED_BYTE, texData);
  256. }
  257. /*****************************************************************/
  258. void
  259. checkErrors(void)
  260. {
  261. GLenum error;
  262. while ((error = glGetError()) != GL_NO_ERROR) {
  263. fprintf(stderr, "Error: %s\n", (char *) gluErrorString(error));
  264. }
  265. }
  266. void
  267. drawCube(void)
  268. {
  269. glBegin(GL_QUADS);
  270. glNormal3f(-1.0, 0.0, 0.0);
  271. glColor3f(0.80, 0.50, 0.50);
  272. glVertex3f(-0.5, -0.5, -0.5);
  273. glVertex3f(-0.5, -0.5, 0.5);
  274. glVertex3f(-0.5, 0.5, 0.5);
  275. glVertex3f(-0.5, 0.5, -0.5);
  276. glNormal3f(1.0, 0.0, 0.0);
  277. glColor3f(0.50, 0.80, 0.50);
  278. glVertex3f(0.5, 0.5, 0.5);
  279. glVertex3f(0.5, -0.5, 0.5);
  280. glVertex3f(0.5, -0.5, -0.5);
  281. glVertex3f(0.5, 0.5, -0.5);
  282. glNormal3f(0.0, -1.0, 0.0);
  283. glColor3f(0.50, 0.50, 0.80);
  284. glVertex3f(-0.5, -0.5, -0.5);
  285. glVertex3f(0.5, -0.5, -0.5);
  286. glVertex3f(0.5, -0.5, 0.5);
  287. glVertex3f(-0.5, -0.5, 0.5);
  288. glNormal3f(0.0, 1.0, 0.0);
  289. glColor3f(0.50, 0.80, 0.80);
  290. glVertex3f(0.5, 0.5, 0.5);
  291. glVertex3f(0.5, 0.5, -0.5);
  292. glVertex3f(-0.5, 0.5, -0.5);
  293. glVertex3f(-0.5, 0.5, 0.5);
  294. glNormal3f(0.0, 0.0, -1.0);
  295. glColor3f(0.80, 0.50, 0.80);
  296. glVertex3f(-0.5, -0.5, -0.5);
  297. glVertex3f(-0.5, 0.5, -0.5);
  298. glVertex3f(0.5, 0.5, -0.5);
  299. glVertex3f(0.5, -0.5, -0.5);
  300. glNormal3f(0.0, 0.0, 1.0);
  301. glColor3f(1.00, 0.80, 0.50);
  302. glVertex3f(0.5, 0.5, 0.5);
  303. glVertex3f(-0.5, 0.5, 0.5);
  304. glVertex3f(-0.5, -0.5, 0.5);
  305. glVertex3f(0.5, -0.5, 0.5);
  306. glEnd();
  307. }
  308. void
  309. drawDodecahedron(void)
  310. {
  311. #define A (0.5 * 1.61803) /* (sqrt(5) + 1) / 2 */
  312. #define B (0.5 * 0.61803) /* (sqrt(5) - 1) / 2 */
  313. #define C (0.5 * 1.0)
  314. GLfloat vertexes[20][3] =
  315. {
  316. {-A, 0.0, B},
  317. {-A, 0.0, -B},
  318. {A, 0.0, -B},
  319. {A, 0.0, B},
  320. {B, -A, 0.0},
  321. {-B, -A, 0.0},
  322. {-B, A, 0.0},
  323. {B, A, 0.0},
  324. {0.0, B, -A},
  325. {0.0, -B, -A},
  326. {0.0, -B, A},
  327. {0.0, B, A},
  328. {-C, -C, C},
  329. {-C, -C, -C},
  330. {C, -C, -C},
  331. {C, -C, C},
  332. {-C, C, C},
  333. {-C, C, -C},
  334. {C, C, -C},
  335. {C, C, C},
  336. };
  337. #undef A
  338. #undef B
  339. #undef C
  340. GLint polygons[12][5] =
  341. {
  342. {0, 12, 10, 11, 16},
  343. {1, 17, 8, 9, 13},
  344. {2, 14, 9, 8, 18},
  345. {3, 19, 11, 10, 15},
  346. {4, 14, 2, 3, 15},
  347. {5, 12, 0, 1, 13},
  348. {6, 17, 1, 0, 16},
  349. {7, 19, 3, 2, 18},
  350. {8, 17, 6, 7, 18},
  351. {9, 14, 4, 5, 13},
  352. {10, 12, 5, 4, 15},
  353. {11, 19, 7, 6, 16},
  354. };
  355. int i;
  356. glColor3f(0.75, 0.75, 0.75);
  357. for (i = 0; i < 12; ++i) {
  358. GLfloat *p0, *p1, *p2, d;
  359. GLfloat u[3], v[3], n[3];
  360. p0 = &vertexes[polygons[i][0]][0];
  361. p1 = &vertexes[polygons[i][1]][0];
  362. p2 = &vertexes[polygons[i][2]][0];
  363. u[0] = p2[0] - p1[0];
  364. u[1] = p2[1] - p1[1];
  365. u[2] = p2[2] - p1[2];
  366. v[0] = p0[0] - p1[0];
  367. v[1] = p0[1] - p1[1];
  368. v[2] = p0[2] - p1[2];
  369. n[0] = u[1] * v[2] - u[2] * v[1];
  370. n[1] = u[2] * v[0] - u[0] * v[2];
  371. n[2] = u[0] * v[1] - u[1] * v[0];
  372. d = 1.0 / sqrt(n[0] * n[0] + n[1] * n[1] + n[2] * n[2]);
  373. n[0] *= d;
  374. n[1] *= d;
  375. n[2] *= d;
  376. glBegin(GL_POLYGON);
  377. glNormal3fv(n);
  378. glVertex3fv(p0);
  379. glVertex3fv(p1);
  380. glVertex3fv(p2);
  381. glVertex3fv(vertexes[polygons[i][3]]);
  382. glVertex3fv(vertexes[polygons[i][4]]);
  383. glEnd();
  384. }
  385. }
  386. void
  387. drawSphere(void)
  388. {
  389. int numMajor = 24;
  390. int numMinor = 32;
  391. float radius = 0.8;
  392. double majorStep = (M_PI / numMajor);
  393. double minorStep = (2.0 * M_PI / numMinor);
  394. int i, j;
  395. glColor3f(0.50, 0.50, 0.50);
  396. for (i = 0; i < numMajor; ++i) {
  397. double a = i * majorStep;
  398. double b = a + majorStep;
  399. double r0 = radius * sin(a);
  400. double r1 = radius * sin(b);
  401. GLfloat z0 = radius * cos(a);
  402. GLfloat z1 = radius * cos(b);
  403. glBegin(GL_TRIANGLE_STRIP);
  404. for (j = 0; j <= numMinor; ++j) {
  405. double c = j * minorStep;
  406. GLfloat x = cos(c);
  407. GLfloat y = sin(c);
  408. glNormal3f((x * r0) / radius, (y * r0) / radius, z0 / radius);
  409. glTexCoord2f(j / (GLfloat) numMinor, i / (GLfloat) numMajor);
  410. glVertex3f(x * r0, y * r0, z0);
  411. glNormal3f((x * r1) / radius, (y * r1) / radius, z1 / radius);
  412. glTexCoord2f(j / (GLfloat) numMinor, (i + 1) / (GLfloat) numMajor);
  413. glVertex3f(x * r1, y * r1, z1);
  414. }
  415. glEnd();
  416. }
  417. }
  418. /*****************************************************************/
  419. float xmin = -0.035, xmax = 0.035;
  420. float ymin = -0.035, ymax = 0.035;
  421. float nnear = 0.1;
  422. float ffar = 1.9;
  423. float distance = -1.0;
  424. static void
  425. loadTextureProjection(int texUnit, GLfloat m[16])
  426. {
  427. GLfloat mInverse[4][4];
  428. /* Should use true inverse, but since m consists only of rotations, we can
  429. just use the transpose. */
  430. matrixTranspose((GLfloat *) mInverse, m);
  431. ActiveTexture(GL_TEXTURE0_ARB + texUnit);
  432. glMatrixMode(GL_TEXTURE);
  433. glLoadIdentity();
  434. glTranslatef(0.5, 0.5, 0.0);
  435. glScalef(0.5, 0.5, 1.0);
  436. glFrustum(xmin, xmax, ymin, ymax, nnear, ffar);
  437. glTranslatef(0.0, 0.0, distance);
  438. glMultMatrixf((GLfloat *) mInverse);
  439. glMatrixMode(GL_MODELVIEW);
  440. }
  441. static void
  442. drawTextureProjection(void)
  443. {
  444. float t = ffar / nnear;
  445. GLfloat n[4][3];
  446. GLfloat f[4][3];
  447. n[0][0] = xmin;
  448. n[0][1] = ymin;
  449. n[0][2] = -(nnear + distance);
  450. n[1][0] = xmax;
  451. n[1][1] = ymin;
  452. n[1][2] = -(nnear + distance);
  453. n[2][0] = xmax;
  454. n[2][1] = ymax;
  455. n[2][2] = -(nnear + distance);
  456. n[3][0] = xmin;
  457. n[3][1] = ymax;
  458. n[3][2] = -(nnear + distance);
  459. f[0][0] = xmin * t;
  460. f[0][1] = ymin * t;
  461. f[0][2] = -(ffar + distance);
  462. f[1][0] = xmax * t;
  463. f[1][1] = ymin * t;
  464. f[1][2] = -(ffar + distance);
  465. f[2][0] = xmax * t;
  466. f[2][1] = ymax * t;
  467. f[2][2] = -(ffar + distance);
  468. f[3][0] = xmin * t;
  469. f[3][1] = ymax * t;
  470. f[3][2] = -(ffar + distance);
  471. glColor3f(1.0, 1.0, 0.0);
  472. glBegin(GL_LINE_LOOP);
  473. glVertex3fv(n[0]);
  474. glVertex3fv(n[1]);
  475. glVertex3fv(n[2]);
  476. glVertex3fv(n[3]);
  477. glVertex3fv(f[3]);
  478. glVertex3fv(f[2]);
  479. glVertex3fv(f[1]);
  480. glVertex3fv(f[0]);
  481. glVertex3fv(n[0]);
  482. glVertex3fv(n[1]);
  483. glVertex3fv(f[1]);
  484. glVertex3fv(f[0]);
  485. glVertex3fv(f[3]);
  486. glVertex3fv(f[2]);
  487. glVertex3fv(n[2]);
  488. glVertex3fv(n[3]);
  489. glEnd();
  490. }
  491. /*****************************************************************/
  492. void
  493. initialize(void)
  494. {
  495. GLfloat light0Pos[4] =
  496. {0.3, 0.3, 0.0, 1.0};
  497. GLfloat matAmb[4] =
  498. {0.01, 0.01, 0.01, 1.00};
  499. GLfloat matDiff[4] =
  500. {0.65, 0.65, 0.65, 1.00};
  501. GLfloat matSpec[4] =
  502. {0.30, 0.30, 0.30, 1.00};
  503. GLfloat matShine = 10.0;
  504. GLfloat eyePlaneS[] =
  505. {1.0, 0.0, 0.0, 0.0};
  506. GLfloat eyePlaneT[] =
  507. {0.0, 1.0, 0.0, 0.0};
  508. GLfloat eyePlaneR[] =
  509. {0.0, 0.0, 1.0, 0.0};
  510. GLfloat eyePlaneQ[] =
  511. {0.0, 0.0, 0.0, 1.0};
  512. int i;
  513. /* Setup Misc. */
  514. glClearColor(0.41, 0.41, 0.31, 0.0);
  515. glEnable(GL_DEPTH_TEST);
  516. /* glLineWidth(2.0);*/
  517. glCullFace(GL_FRONT);
  518. glEnable(GL_CULL_FACE);
  519. glMatrixMode(GL_PROJECTION);
  520. glFrustum(-0.5, 0.5, -0.5, 0.5, 1, 3);
  521. glMatrixMode(GL_MODELVIEW);
  522. glTranslatef(0, 0, -2);
  523. matrixIdentity((GLfloat *) objectXform);
  524. for (i = 0; i < NumTextures; i++) {
  525. matrixIdentity((GLfloat *) textureXform[i]);
  526. }
  527. glMatrixMode(GL_PROJECTION);
  528. glPushMatrix();
  529. glLoadIdentity();
  530. glOrtho(0, 1, 0, 1, -1, 1);
  531. glMatrixMode(GL_MODELVIEW);
  532. glPushMatrix();
  533. glLoadIdentity();
  534. glRasterPos2i(0, 0);
  535. glPopMatrix();
  536. glMatrixMode(GL_PROJECTION);
  537. glPopMatrix();
  538. glMatrixMode(GL_MODELVIEW);
  539. /* Setup Lighting */
  540. glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, matAmb);
  541. glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matDiff);
  542. glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, matSpec);
  543. glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, matShine);
  544. glEnable(GL_COLOR_MATERIAL);
  545. glLightfv(GL_LIGHT0, GL_POSITION, light0Pos);
  546. glEnable(GL_LIGHT0);
  547. glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
  548. glEnable(GL_LIGHTING);
  549. /* Setup Texture */
  550. (*loadTexture) ();
  551. for (i = 0; i < NumTextures; i++) {
  552. ActiveTexture(GL_TEXTURE0_ARB + i);
  553. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  554. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  555. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  556. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  557. glTexGenfv(GL_S, GL_EYE_PLANE, eyePlaneS);
  558. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  559. glTexGenfv(GL_T, GL_EYE_PLANE, eyePlaneT);
  560. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  561. glTexGenfv(GL_R, GL_EYE_PLANE, eyePlaneR);
  562. glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  563. glTexGenfv(GL_Q, GL_EYE_PLANE, eyePlaneQ);
  564. }
  565. }
  566. void
  567. display(void)
  568. {
  569. int i;
  570. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  571. if (textureEnabled) {
  572. if (mode == MoveTexture || mode == MoveView) {
  573. /* Have OpenGL compute the new transformation (simple but slow). */
  574. for (i = 0; i < NumTextures; i++) {
  575. glPushMatrix();
  576. glLoadIdentity();
  577. #if 0
  578. if (i & 1)
  579. glRotatef(angle, axis[0], axis[1], axis[2]);
  580. else
  581. #endif
  582. glRotatef(angle*(i+1), axis[0], axis[1], axis[2]);
  583. glMultMatrixf((GLfloat *) textureXform[i]);
  584. glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) textureXform[i]);
  585. glPopMatrix();
  586. }
  587. }
  588. for (i = 0; i < NumTextures; i++) {
  589. loadTextureProjection(i, (GLfloat *) textureXform[i]);
  590. }
  591. if (showProjection) {
  592. for (i = 0; i < NumTextures; i++) {
  593. ActiveTexture(GL_TEXTURE0_ARB + i);
  594. glPushMatrix();
  595. glMultMatrixf((GLfloat *) textureXform[i]);
  596. glDisable(GL_LIGHTING);
  597. drawTextureProjection();
  598. glEnable(GL_LIGHTING);
  599. glPopMatrix();
  600. }
  601. }
  602. for (i = 0; i < NumTextures; i++) {
  603. ActiveTexture(GL_TEXTURE0_ARB + i);
  604. glEnable(GL_TEXTURE_2D);
  605. glEnable(GL_TEXTURE_GEN_S);
  606. glEnable(GL_TEXTURE_GEN_T);
  607. glEnable(GL_TEXTURE_GEN_R);
  608. glEnable(GL_TEXTURE_GEN_Q);
  609. }
  610. }
  611. if (mode == MoveObject || mode == MoveView) {
  612. /* Have OpenGL compute the new transformation (simple but slow). */
  613. glPushMatrix();
  614. glLoadIdentity();
  615. glRotatef(angle, axis[0], axis[1], axis[2]);
  616. glMultMatrixf((GLfloat *) objectXform);
  617. glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) objectXform);
  618. glPopMatrix();
  619. }
  620. glPushMatrix();
  621. glMultMatrixf((GLfloat *) objectXform);
  622. (*drawObject) ();
  623. glPopMatrix();
  624. for (i = 0; i < NumTextures; i++) {
  625. ActiveTexture(GL_TEXTURE0_ARB + i);
  626. glDisable(GL_TEXTURE_2D);
  627. glDisable(GL_TEXTURE_GEN_S);
  628. glDisable(GL_TEXTURE_GEN_T);
  629. glDisable(GL_TEXTURE_GEN_R);
  630. glDisable(GL_TEXTURE_GEN_Q);
  631. }
  632. if (zoomFactor > 1.0) {
  633. glDisable(GL_DEPTH_TEST);
  634. glCopyPixels(0, 0, winWidth / zoomFactor, winHeight / zoomFactor, GL_COLOR);
  635. glEnable(GL_DEPTH_TEST);
  636. }
  637. glFlush();
  638. glutSwapBuffers();
  639. checkErrors();
  640. }
  641. /*****************************************************************/
  642. /* simple trackball-like motion control */
  643. float lastPos[3];
  644. int lastTime;
  645. void
  646. ptov(int x, int y, int width, int height, float v[3])
  647. {
  648. float d, a;
  649. /* project x,y onto a hemi-sphere centered within width, height */
  650. v[0] = (2.0 * x - width) / width;
  651. v[1] = (height - 2.0 * y) / height;
  652. d = sqrt(v[0] * v[0] + v[1] * v[1]);
  653. v[2] = cos((M_PI / 2.0) * ((d < 1.0) ? d : 1.0));
  654. a = 1.0 / sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
  655. v[0] *= a;
  656. v[1] *= a;
  657. v[2] *= a;
  658. }
  659. void
  660. startMotion(int x, int y, int but, int time)
  661. {
  662. if (but == GLUT_LEFT_BUTTON) {
  663. mode = MoveView;
  664. } else if (but == GLUT_MIDDLE_BUTTON) {
  665. mode = MoveTexture;
  666. } else {
  667. return;
  668. }
  669. lastTime = time;
  670. ptov(x, y, winWidth, winHeight, lastPos);
  671. }
  672. void
  673. animate(void)
  674. {
  675. glutPostRedisplay();
  676. }
  677. void
  678. vis(int visible)
  679. {
  680. if (visible == GLUT_VISIBLE) {
  681. if (redrawContinuously)
  682. glutIdleFunc(animate);
  683. } else {
  684. if (redrawContinuously)
  685. glutIdleFunc(NULL);
  686. }
  687. }
  688. void
  689. stopMotion(int but, int time)
  690. {
  691. if ((but == GLUT_LEFT_BUTTON && mode == MoveView) ||
  692. (but == GLUT_MIDDLE_BUTTON && mode == MoveTexture)) {
  693. } else {
  694. return;
  695. }
  696. if (time == lastTime) {
  697. /* redrawContinuously = GL_TRUE;*/
  698. glutIdleFunc(animate);
  699. } else {
  700. angle = 0.0;
  701. redrawContinuously = GL_FALSE;
  702. glutIdleFunc(0);
  703. }
  704. if (!redrawContinuously) {
  705. mode = MoveNone;
  706. }
  707. }
  708. void
  709. trackMotion(int x, int y)
  710. {
  711. float curPos[3], dx, dy, dz;
  712. ptov(x, y, winWidth, winHeight, curPos);
  713. dx = curPos[0] - lastPos[0];
  714. dy = curPos[1] - lastPos[1];
  715. dz = curPos[2] - lastPos[2];
  716. angle = 90.0 * sqrt(dx * dx + dy * dy + dz * dz);
  717. axis[0] = lastPos[1] * curPos[2] - lastPos[2] * curPos[1];
  718. axis[1] = lastPos[2] * curPos[0] - lastPos[0] * curPos[2];
  719. axis[2] = lastPos[0] * curPos[1] - lastPos[1] * curPos[0];
  720. lastTime = glutGet(GLUT_ELAPSED_TIME);
  721. lastPos[0] = curPos[0];
  722. lastPos[1] = curPos[1];
  723. lastPos[2] = curPos[2];
  724. glutPostRedisplay();
  725. }
  726. /*****************************************************************/
  727. void
  728. object(void)
  729. {
  730. static int object;
  731. object++;
  732. object %= 3;
  733. switch (object) {
  734. case 0:
  735. drawObject = drawCube;
  736. break;
  737. case 1:
  738. drawObject = drawDodecahedron;
  739. break;
  740. case 2:
  741. drawObject = drawSphere;
  742. break;
  743. default:
  744. break;
  745. }
  746. }
  747. static void
  748. nop(void)
  749. {
  750. }
  751. void
  752. texture(void)
  753. {
  754. static int texture = 0;
  755. texture++;
  756. texture %= 3;
  757. if (texture == 1 && texFilename == NULL) {
  758. /* Skip file texture if not loaded. */
  759. texture++;
  760. }
  761. switch (texture) {
  762. case 0:
  763. loadTexture = nop;
  764. textureEnabled = GL_FALSE;
  765. break;
  766. case 1:
  767. loadTexture = loadImageTextures;
  768. (*loadTexture) ();
  769. textureEnabled = GL_TRUE;
  770. break;
  771. case 2:
  772. loadTexture = loadSpotlightTexture;
  773. (*loadTexture) ();
  774. textureEnabled = GL_TRUE;
  775. break;
  776. default:
  777. break;
  778. }
  779. }
  780. void
  781. help(void)
  782. {
  783. printf("'h' - help\n");
  784. printf("'l' - toggle linear/nearest filter\n");
  785. printf("'s' - toggle projection frustum\n");
  786. printf("'t' - toggle projected texture\n");
  787. printf("'o' - toggle object\n");
  788. printf("'z' - increase zoom factor\n");
  789. printf("'Z' - decrease zoom factor\n");
  790. printf("left mouse - move view\n");
  791. printf("middle mouse - move projection\n");
  792. }
  793. /* ARGSUSED1 */
  794. void
  795. key(unsigned char key, int x, int y)
  796. {
  797. switch (key) {
  798. case '\033':
  799. exit(0);
  800. break;
  801. case 'l':
  802. linearFilter = !linearFilter;
  803. (*loadTexture) ();
  804. break;
  805. case 's':
  806. showProjection = !showProjection;
  807. break;
  808. case 't':
  809. texture();
  810. break;
  811. case 'o':
  812. object();
  813. break;
  814. case 'z':
  815. zoomFactor += 1.0;
  816. glPixelZoom(zoomFactor, zoomFactor);
  817. glViewport(0, 0, winWidth / zoomFactor, winHeight / zoomFactor);
  818. break;
  819. case 'Z':
  820. zoomFactor -= 1.0;
  821. if (zoomFactor < 1.0)
  822. zoomFactor = 1.0;
  823. glPixelZoom(zoomFactor, zoomFactor);
  824. glViewport(0, 0, winWidth / zoomFactor, winHeight / zoomFactor);
  825. break;
  826. case 'h':
  827. help();
  828. break;
  829. }
  830. glutPostRedisplay();
  831. }
  832. void
  833. mouse(int button, int state, int x, int y)
  834. {
  835. if (state == GLUT_DOWN)
  836. startMotion(x, y, button, glutGet(GLUT_ELAPSED_TIME));
  837. else if (state == GLUT_UP)
  838. stopMotion(button, glutGet(GLUT_ELAPSED_TIME));
  839. glutPostRedisplay();
  840. }
  841. void
  842. reshape(int w, int h)
  843. {
  844. winWidth = w;
  845. winHeight = h;
  846. glViewport(0, 0, w / zoomFactor, h / zoomFactor);
  847. }
  848. void
  849. menu(int selection)
  850. {
  851. if (selection == 666) {
  852. exit(0);
  853. }
  854. key((unsigned char) selection, 0, 0);
  855. }
  856. int
  857. main(int argc, char **argv)
  858. {
  859. glutInit(&argc, argv);
  860. if (argc > 1) {
  861. NumTextures = atoi(argv[1]);
  862. }
  863. assert(NumTextures <= MAX_TEX);
  864. glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
  865. (void) glutCreateWindow("projtex");
  866. loadTexture = loadImageTextures;
  867. drawObject = drawCube;
  868. initialize();
  869. glutDisplayFunc(display);
  870. glutKeyboardFunc(key);
  871. glutReshapeFunc(reshape);
  872. glutMouseFunc(mouse);
  873. glutMotionFunc(trackMotion);
  874. glutVisibilityFunc(vis);
  875. glutCreateMenu(menu);
  876. glutAddMenuEntry("Toggle showing projection", 's');
  877. glutAddMenuEntry("Switch texture", 't');
  878. glutAddMenuEntry("Switch object", 'o');
  879. glutAddMenuEntry("Toggle filtering", 'l');
  880. glutAddMenuEntry("Quit", 666);
  881. glutAttachMenu(GLUT_RIGHT_BUTTON);
  882. texture();
  883. glutMainLoop();
  884. return 0; /* ANSI C requires main to return int. */
  885. }