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