home *** CD-ROM | disk | FTP | other *** search
/ Amiga Magazin: Amiga-CD 2000 April & May / AMIGA_2000_04.iso / patches / mesa3.1 / samples / stretch.c < prev    next >
C/C++ Source or Header  |  2000-01-01  |  8KB  |  376 lines

  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.  
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <math.h>
  29. #include <GL/glut.h>
  30.  
  31.  
  32. #define STEPCOUNT 40
  33. #define FALSE 0
  34. #define TRUE 1
  35. #define MAX(a, b) (((a) > (b)) ? (a) : (b))
  36. #define MIN(a, b) (((a) < (b)) ? (a) : (b))
  37.  
  38.  
  39. enum {
  40.     OP_NOOP = 0,
  41.     OP_STRETCH,
  42.     OP_DRAWPOINT,
  43.     OP_DRAWIMAGE
  44. };
  45.  
  46.  
  47. typedef struct _cRec {
  48.     float x, y;
  49. } cRec;
  50.  
  51. typedef struct _vertexRec {
  52.     float x, y;
  53.     float dX, dY;
  54.     float tX, tY;
  55. } vertexRec;
  56.  
  57.  
  58. #include "loadppm.c"
  59.  
  60. GLenum doubleBuffer;
  61. int imageSizeX, imageSizeY;
  62. char *fileName = 0;
  63. PPMImage *image;
  64. cRec cList[50];
  65. vertexRec vList[5];
  66. int cCount, cIndex[2], cStep;
  67. GLenum op = OP_NOOP;
  68.  
  69.  
  70. void DrawImage(void)
  71. {
  72.  
  73.     glRasterPos2i(0, 0);
  74.     glDrawPixels(image->sizeX, image->sizeY, GL_RGB, GL_UNSIGNED_BYTE,
  75.          image->data);
  76.  
  77.     glFlush();
  78.     if (doubleBuffer) {
  79.     glutSwapBuffers();
  80.     }
  81.  
  82.     glRasterPos2i(0, 0);
  83.     glDrawPixels(image->sizeX, image->sizeY, GL_RGB, GL_UNSIGNED_BYTE,
  84.          image->data);
  85. }
  86.  
  87. void DrawPoint(void)
  88. {
  89.     int i;
  90.  
  91.     glColor3f(1.0, 0.0, 1.0);
  92.     glPointSize(3.0);
  93.     glBegin(GL_POINTS);
  94.     for (i = 0; i < cCount; i++) {
  95.         glVertex2f(cList[i].x, cList[i].y);
  96.     }
  97.     glEnd();
  98.  
  99.     glFlush();
  100.     if (doubleBuffer) {
  101.     glutSwapBuffers();
  102.     }
  103. }
  104.  
  105. void InitVList(void)
  106. {
  107.  
  108.     vList[0].x = 0.0;
  109.     vList[0].y = 0.0;
  110.     vList[0].dX = 0.0;
  111.     vList[0].dY = 0.0;
  112.     vList[0].tX = 0.0;
  113.     vList[0].tY = 0.0;
  114.  
  115.     vList[1].x = (float)imageSizeX;
  116.     vList[1].y = 0.0;
  117.     vList[1].dX = 0.0;
  118.     vList[1].dY = 0.0;
  119.     vList[1].tX = 1.0;
  120.     vList[1].tY = 0.0;
  121.  
  122.     vList[2].x = (float)imageSizeX;
  123.     vList[2].y = (float)imageSizeY;
  124.     vList[2].dX = 0.0;
  125.     vList[2].dY = 0.0;
  126.     vList[2].tX = 1.0;
  127.     vList[2].tY = 1.0;
  128.  
  129.     vList[3].x = 0.0;
  130.     vList[3].y = (float)imageSizeY;
  131.     vList[3].dX = 0.0;
  132.     vList[3].dY = 0.0;
  133.     vList[3].tX = 0.0;
  134.     vList[3].tY = 1.0;
  135.  
  136.     vList[4].x = cList[0].x;
  137.     vList[4].y = cList[0].y;
  138.     vList[4].dX = (cList[1].x - cList[0].x) / STEPCOUNT;
  139.     vList[4].dY = (cList[1].y - cList[0].y) / STEPCOUNT;
  140.     vList[4].tX = cList[0].x / (float)imageSizeX;
  141.     vList[4].tY = cList[0].y / (float)imageSizeY;
  142. }
  143.  
  144. void ScaleImage(int sizeX, int sizeY)
  145. {
  146.     GLubyte *buf;
  147.  
  148.     buf = (GLubyte *)malloc(3*sizeX*sizeY);
  149.     gluScaleImage(GL_RGB, image->sizeX, image->sizeY, GL_UNSIGNED_BYTE,
  150.                   image->data, sizeX, sizeY, GL_UNSIGNED_BYTE, buf);
  151.     free(image->data);
  152.     image->data = buf;
  153.     image->sizeX = sizeX;
  154.     image->sizeY = sizeY;
  155. }
  156.  
  157. void SetPoint(int x, int y)
  158. {
  159.  
  160.     cList[cCount].x = (float)x;
  161.     cList[cCount].y = (float)y;
  162.     cCount++;
  163. }
  164.  
  165. void Stretch(void)
  166. {
  167.  
  168.     glBegin(GL_TRIANGLES);
  169.     glTexCoord2f(vList[0].tX, vList[0].tY);
  170.     glVertex2f(vList[0].x, vList[0].y);
  171.     glTexCoord2f(vList[1].tX, vList[1].tY);
  172.     glVertex2f(vList[1].x, vList[1].y);
  173.     glTexCoord2f(vList[4].tX, vList[4].tY);
  174.     glVertex2f(vList[4].x, vList[4].y);
  175.     glEnd();
  176.  
  177.     glBegin(GL_TRIANGLES);
  178.     glTexCoord2f(vList[1].tX, vList[1].tY);
  179.     glVertex2f(vList[1].x, vList[1].y);
  180.     glTexCoord2f(vList[2].tX, vList[2].tY);
  181.     glVertex2f(vList[2].x, vList[2].y);
  182.     glTexCoord2f(vList[4].tX, vList[4].tY);
  183.     glVertex2f(vList[4].x, vList[4].y);
  184.     glEnd();
  185.  
  186.     glBegin(GL_TRIANGLES);
  187.     glTexCoord2f(vList[2].tX, vList[2].tY);
  188.     glVertex2f(vList[2].x, vList[2].y);
  189.     glTexCoord2f(vList[3].tX, vList[3].tY);
  190.     glVertex2f(vList[3].x, vList[3].y);
  191.     glTexCoord2f(vList[4].tX, vList[4].tY);
  192.     glVertex2f(vList[4].x, vList[4].y);
  193.     glEnd();
  194.  
  195.     glBegin(GL_TRIANGLES);
  196.     glTexCoord2f(vList[3].tX, vList[3].tY);
  197.     glVertex2f(vList[3].x, vList[3].y);
  198.     glTexCoord2f(vList[0].tX, vList[0].tY);
  199.     glVertex2f(vList[0].x, vList[0].y);
  200.     glTexCoord2f(vList[4].tX, vList[4].tY);
  201.     glVertex2f(vList[4].x, vList[4].y);
  202.     glEnd();
  203.  
  204.     glFlush();
  205.     if (doubleBuffer) {
  206.     glutSwapBuffers();
  207.     }
  208.  
  209.     if (++cStep < STEPCOUNT) {
  210.     vList[4].x += vList[4].dX;
  211.     vList[4].y += vList[4].dY;
  212.     } else {
  213.     cIndex[0] = cIndex[1];
  214.     cIndex[1] = cIndex[1] + 1;
  215.     if (cIndex[1] == cCount) {
  216.         cIndex[1] = 0;
  217.     }
  218.     vList[4].dX = (cList[cIndex[1]].x - cList[cIndex[0]].x) / STEPCOUNT;
  219.     vList[4].dY = (cList[cIndex[1]].y - cList[cIndex[0]].y) / STEPCOUNT;
  220.     cStep = 0;
  221.     }
  222. }
  223.  
  224. void Key(unsigned char key, int x, int y)
  225. {
  226.  
  227.     switch (key) {
  228.       case 27:
  229.     free(image->data);
  230.         exit(1);
  231.       case 32:
  232.     if (cCount > 1) {
  233.         InitVList();
  234.         cIndex[0] = 0;
  235.         cIndex[1] = 1;
  236.         cStep = 0;
  237.         glEnable(GL_TEXTURE_2D);
  238.         op = OP_STRETCH;
  239.     }
  240.     break;
  241.       default:
  242.     return;
  243.     }
  244.  
  245.     glutPostRedisplay();
  246. }
  247.  
  248. void Mouse(int button, int state, int mouseX, int mouseY)
  249. {
  250.  
  251.     if (state != GLUT_DOWN)
  252.     return;
  253.  
  254.     if (op == OP_STRETCH) {
  255.     glDisable(GL_TEXTURE_2D);
  256.     cCount = 0;
  257.     op = OP_DRAWIMAGE;
  258.     } else {
  259.     SetPoint(mouseX, imageSizeY-mouseY);
  260.     op = OP_DRAWPOINT;
  261.     }
  262.  
  263.     glutPostRedisplay();
  264. }
  265.  
  266. void Animate(void)
  267. {
  268.  
  269.     switch (op) {
  270.       case OP_STRETCH:
  271.     Stretch();
  272.     break;
  273.       case OP_DRAWPOINT:
  274.     DrawPoint();
  275.     break;
  276.       case OP_DRAWIMAGE:
  277.     DrawImage();
  278.     break;
  279.       default:
  280.         break;
  281.     }
  282. }
  283.  
  284. static GLenum Args(int argc, char **argv)
  285. {
  286.     GLint i;
  287.  
  288.     doubleBuffer = GL_FALSE;
  289.  
  290.     for (i = 1; i < argc; i++) {
  291.     if (strcmp(argv[i], "-sb") == 0) {
  292.         doubleBuffer = GL_FALSE;
  293.     } else if (strcmp(argv[i], "-db") == 0) {
  294.         doubleBuffer = GL_TRUE;
  295.     } else if (strcmp(argv[i], "-f") == 0) {
  296.         if (i+1 >= argc || argv[i+1][0] == '-') {
  297.         printf("-f (No file name).\n");
  298.         return GL_FALSE;
  299.         } else {
  300.         fileName = argv[++i];
  301.         }
  302.     } else {
  303.         printf("%s (Bad option).\n", argv[i]);
  304.         return GL_FALSE;
  305.     }
  306.     }
  307.     return GL_TRUE;
  308. }
  309.  
  310. void GLUTCALLBACK glut_post_redisplay_p(void)
  311. {
  312.       glutPostRedisplay();
  313. }
  314.  
  315. int main(int argc, char **argv)
  316. {
  317.     GLenum type;
  318.  
  319.     glutInit(&argc, argv);
  320.  
  321.     if (Args(argc, argv) == GL_FALSE) {
  322.     exit(1);
  323.     }
  324.  
  325.     if (fileName == 0) {
  326.     printf("No image file.\n");
  327.     exit(1);
  328.     }
  329.  
  330.     image = LoadPPM(fileName);
  331.  
  332.     /* changed powf and logf to pow and log -Brian */
  333.     imageSizeX = (int)pow(2.0, (float)((int)(log(image->sizeX)/log(2.0))));
  334.     imageSizeY = (int)pow(2.0, (float)((int)(log(image->sizeY)/log(2.0))));
  335.  
  336.     glutInitWindowPosition(0, 0); glutInitWindowSize( imageSizeX, imageSizeY);
  337.  
  338.     type = GLUT_RGB;
  339.     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
  340.     glutInitDisplayMode(type);
  341.  
  342.     if (glutCreateWindow("Stretch") == GL_FALSE) {
  343.         exit(1);
  344.     }
  345.  
  346.     glViewport(0, 0, imageSizeX, imageSizeY);
  347.     gluOrtho2D(0, imageSizeX, 0, imageSizeY);
  348.     glClearColor(0.0, 0.0, 0.0, 0.0);
  349.  
  350.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  351.     glPixelStorei(GL_PACK_ALIGNMENT, 1);
  352.  
  353.     ScaleImage(imageSizeX, imageSizeY);
  354.  
  355.     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
  356.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  357.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  358.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  359.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  360.     glTexImage2D(GL_TEXTURE_2D, 0, 3, image->sizeX, image->sizeY, 0,
  361.                  GL_RGB, GL_UNSIGNED_BYTE, (unsigned char *)image->data);
  362.  
  363.     cCount = 0;
  364.     cIndex[0] = 0;
  365.     cIndex[1] = 0;
  366.     cStep = 0;
  367.     op = OP_DRAWIMAGE;
  368.  
  369.     glutKeyboardFunc(Key);
  370.     glutMouseFunc(Mouse);
  371.     glutDisplayFunc(Animate);
  372.     glutIdleFunc(glut_post_redisplay_p);
  373.     glutMainLoop();
  374.     return 0;
  375. }
  376.