Clone of mesa.
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.

stretch.c 8.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. /*
  2. * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
  3. *
  4. * Permission to use, copy, modify, distribute, and sell this software and
  5. * its documentation for any purpose is hereby granted without fee, provided
  6. * that (i) the above copyright notices and this permission notice appear in
  7. * all copies of the software and related documentation, and (ii) the name of
  8. * Silicon Graphics may not be used in any advertising or
  9. * publicity relating to the software without the specific, prior written
  10. * permission of Silicon Graphics.
  11. *
  12. * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
  13. * ANY KIND,
  14. * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
  15. * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  16. *
  17. * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
  18. * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  19. * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  20. * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
  21. * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  22. * OF THIS SOFTWARE.
  23. */
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include <math.h>
  28. #include <GL/glut.h>
  29. #define STEPCOUNT 40
  30. #define FALSE 0
  31. #define TRUE 1
  32. #define MAX(a, b) (((a) > (b)) ? (a) : (b))
  33. #define MIN(a, b) (((a) < (b)) ? (a) : (b))
  34. enum {
  35. OP_NOOP = 0,
  36. OP_STRETCH,
  37. OP_DRAWPOINT,
  38. OP_DRAWIMAGE
  39. };
  40. typedef struct _cRec {
  41. float x, y;
  42. } cRec;
  43. typedef struct _vertexRec {
  44. float x, y;
  45. float dX, dY;
  46. float tX, tY;
  47. } vertexRec;
  48. #include "loadppm.c"
  49. GLenum doubleBuffer;
  50. int imageSizeX, imageSizeY;
  51. char *fileName = 0;
  52. PPMImage *image;
  53. cRec cList[50];
  54. vertexRec vList[5];
  55. int cCount, cIndex[2], cStep;
  56. GLenum op = OP_NOOP;
  57. void DrawImage(void)
  58. {
  59. glRasterPos2i(0, 0);
  60. glDrawPixels(image->sizeX, image->sizeY, GL_RGB, GL_UNSIGNED_BYTE,
  61. image->data);
  62. glFlush();
  63. if (doubleBuffer) {
  64. glutSwapBuffers();
  65. }
  66. glRasterPos2i(0, 0);
  67. glDrawPixels(image->sizeX, image->sizeY, GL_RGB, GL_UNSIGNED_BYTE,
  68. image->data);
  69. }
  70. void DrawPoint(void)
  71. {
  72. int i;
  73. glColor3f(1.0, 0.0, 1.0);
  74. glPointSize(3.0);
  75. glBegin(GL_POINTS);
  76. for (i = 0; i < cCount; i++) {
  77. glVertex2f(cList[i].x, cList[i].y);
  78. }
  79. glEnd();
  80. glFlush();
  81. if (doubleBuffer) {
  82. glutSwapBuffers();
  83. }
  84. }
  85. void InitVList(void)
  86. {
  87. vList[0].x = 0.0;
  88. vList[0].y = 0.0;
  89. vList[0].dX = 0.0;
  90. vList[0].dY = 0.0;
  91. vList[0].tX = 0.0;
  92. vList[0].tY = 0.0;
  93. vList[1].x = (float)imageSizeX;
  94. vList[1].y = 0.0;
  95. vList[1].dX = 0.0;
  96. vList[1].dY = 0.0;
  97. vList[1].tX = 1.0;
  98. vList[1].tY = 0.0;
  99. vList[2].x = (float)imageSizeX;
  100. vList[2].y = (float)imageSizeY;
  101. vList[2].dX = 0.0;
  102. vList[2].dY = 0.0;
  103. vList[2].tX = 1.0;
  104. vList[2].tY = 1.0;
  105. vList[3].x = 0.0;
  106. vList[3].y = (float)imageSizeY;
  107. vList[3].dX = 0.0;
  108. vList[3].dY = 0.0;
  109. vList[3].tX = 0.0;
  110. vList[3].tY = 1.0;
  111. vList[4].x = cList[0].x;
  112. vList[4].y = cList[0].y;
  113. vList[4].dX = (cList[1].x - cList[0].x) / STEPCOUNT;
  114. vList[4].dY = (cList[1].y - cList[0].y) / STEPCOUNT;
  115. vList[4].tX = cList[0].x / (float)imageSizeX;
  116. vList[4].tY = cList[0].y / (float)imageSizeY;
  117. }
  118. void ScaleImage(int sizeX, int sizeY)
  119. {
  120. GLubyte *buf;
  121. buf = (GLubyte *)malloc(3*sizeX*sizeY);
  122. gluScaleImage(GL_RGB, image->sizeX, image->sizeY, GL_UNSIGNED_BYTE,
  123. image->data, sizeX, sizeY, GL_UNSIGNED_BYTE, buf);
  124. free(image->data);
  125. image->data = buf;
  126. image->sizeX = sizeX;
  127. image->sizeY = sizeY;
  128. }
  129. void SetPoint(int x, int y)
  130. {
  131. cList[cCount].x = (float)x;
  132. cList[cCount].y = (float)y;
  133. cCount++;
  134. }
  135. void Stretch(void)
  136. {
  137. glBegin(GL_TRIANGLES);
  138. glTexCoord2f(vList[0].tX, vList[0].tY);
  139. glVertex2f(vList[0].x, vList[0].y);
  140. glTexCoord2f(vList[1].tX, vList[1].tY);
  141. glVertex2f(vList[1].x, vList[1].y);
  142. glTexCoord2f(vList[4].tX, vList[4].tY);
  143. glVertex2f(vList[4].x, vList[4].y);
  144. glEnd();
  145. glBegin(GL_TRIANGLES);
  146. glTexCoord2f(vList[1].tX, vList[1].tY);
  147. glVertex2f(vList[1].x, vList[1].y);
  148. glTexCoord2f(vList[2].tX, vList[2].tY);
  149. glVertex2f(vList[2].x, vList[2].y);
  150. glTexCoord2f(vList[4].tX, vList[4].tY);
  151. glVertex2f(vList[4].x, vList[4].y);
  152. glEnd();
  153. glBegin(GL_TRIANGLES);
  154. glTexCoord2f(vList[2].tX, vList[2].tY);
  155. glVertex2f(vList[2].x, vList[2].y);
  156. glTexCoord2f(vList[3].tX, vList[3].tY);
  157. glVertex2f(vList[3].x, vList[3].y);
  158. glTexCoord2f(vList[4].tX, vList[4].tY);
  159. glVertex2f(vList[4].x, vList[4].y);
  160. glEnd();
  161. glBegin(GL_TRIANGLES);
  162. glTexCoord2f(vList[3].tX, vList[3].tY);
  163. glVertex2f(vList[3].x, vList[3].y);
  164. glTexCoord2f(vList[0].tX, vList[0].tY);
  165. glVertex2f(vList[0].x, vList[0].y);
  166. glTexCoord2f(vList[4].tX, vList[4].tY);
  167. glVertex2f(vList[4].x, vList[4].y);
  168. glEnd();
  169. glFlush();
  170. if (doubleBuffer) {
  171. glutSwapBuffers();
  172. }
  173. if (++cStep < STEPCOUNT) {
  174. vList[4].x += vList[4].dX;
  175. vList[4].y += vList[4].dY;
  176. } else {
  177. cIndex[0] = cIndex[1];
  178. cIndex[1] = cIndex[1] + 1;
  179. if (cIndex[1] == cCount) {
  180. cIndex[1] = 0;
  181. }
  182. vList[4].dX = (cList[cIndex[1]].x - cList[cIndex[0]].x) / STEPCOUNT;
  183. vList[4].dY = (cList[cIndex[1]].y - cList[cIndex[0]].y) / STEPCOUNT;
  184. cStep = 0;
  185. }
  186. }
  187. void Key(unsigned char key, int x, int y)
  188. {
  189. switch (key) {
  190. case 27:
  191. free(image->data);
  192. exit(1);
  193. case 32:
  194. if (cCount > 1) {
  195. InitVList();
  196. cIndex[0] = 0;
  197. cIndex[1] = 1;
  198. cStep = 0;
  199. glEnable(GL_TEXTURE_2D);
  200. op = OP_STRETCH;
  201. }
  202. break;
  203. default:
  204. return;
  205. }
  206. glutPostRedisplay();
  207. }
  208. void Mouse(int button, int state, int mouseX, int mouseY)
  209. {
  210. if (state != GLUT_DOWN)
  211. return;
  212. if (op == OP_STRETCH) {
  213. glDisable(GL_TEXTURE_2D);
  214. cCount = 0;
  215. op = OP_DRAWIMAGE;
  216. } else {
  217. SetPoint(mouseX, imageSizeY-mouseY);
  218. op = OP_DRAWPOINT;
  219. }
  220. glutPostRedisplay();
  221. }
  222. void Animate(void)
  223. {
  224. switch (op) {
  225. case OP_STRETCH:
  226. Stretch();
  227. break;
  228. case OP_DRAWPOINT:
  229. DrawPoint();
  230. break;
  231. case OP_DRAWIMAGE:
  232. DrawImage();
  233. break;
  234. default:
  235. break;
  236. }
  237. }
  238. static GLenum Args(int argc, char **argv)
  239. {
  240. GLint i;
  241. doubleBuffer = GL_TRUE;
  242. for (i = 1; i < argc; i++) {
  243. if (strcmp(argv[i], "-sb") == 0) {
  244. doubleBuffer = GL_FALSE;
  245. } else if (strcmp(argv[i], "-db") == 0) {
  246. doubleBuffer = GL_TRUE;
  247. } else if (strcmp(argv[i], "-f") == 0) {
  248. if (i+1 >= argc || argv[i+1][0] == '-') {
  249. printf("-f (No file name).\n");
  250. return GL_FALSE;
  251. } else {
  252. fileName = argv[++i];
  253. }
  254. } else {
  255. printf("%s (Bad option).\n", argv[i]);
  256. return GL_FALSE;
  257. }
  258. }
  259. return GL_TRUE;
  260. }
  261. void GLUTCALLBACK glut_post_redisplay_p(void)
  262. {
  263. glutPostRedisplay();
  264. }
  265. int main(int argc, char **argv)
  266. {
  267. GLenum type;
  268. glutInit(&argc, argv);
  269. if (Args(argc, argv) == GL_FALSE) {
  270. exit(1);
  271. }
  272. if (fileName == 0) {
  273. printf("No image file.\n");
  274. exit(1);
  275. }
  276. image = LoadPPM(fileName);
  277. /* changed powf and logf to pow and log -Brian */
  278. imageSizeX = (int)pow(2.0, (float)((int)(log(image->sizeX)/log(2.0))));
  279. imageSizeY = (int)pow(2.0, (float)((int)(log(image->sizeY)/log(2.0))));
  280. glutInitWindowPosition(0, 0); glutInitWindowSize( imageSizeX, imageSizeY);
  281. type = GLUT_RGB;
  282. type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
  283. glutInitDisplayMode(type);
  284. if (glutCreateWindow("Stretch") == GL_FALSE) {
  285. exit(1);
  286. }
  287. glViewport(0, 0, imageSizeX, imageSizeY);
  288. gluOrtho2D(0, imageSizeX, 0, imageSizeY);
  289. glClearColor(0.0, 0.0, 0.0, 0.0);
  290. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  291. glPixelStorei(GL_PACK_ALIGNMENT, 1);
  292. ScaleImage(imageSizeX, imageSizeY);
  293. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
  294. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  295. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  296. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  297. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  298. glTexImage2D(GL_TEXTURE_2D, 0, 3, image->sizeX, image->sizeY, 0,
  299. GL_RGB, GL_UNSIGNED_BYTE, (unsigned char *)image->data);
  300. cCount = 0;
  301. cIndex[0] = 0;
  302. cIndex[1] = 0;
  303. cStep = 0;
  304. op = OP_DRAWIMAGE;
  305. glutKeyboardFunc(Key);
  306. glutMouseFunc(Mouse);
  307. glutDisplayFunc(Animate);
  308. glutIdleFunc(glut_post_redisplay_p);
  309. glutMainLoop();
  310. return 0;
  311. }