132001f49Smrg/* 232001f49Smrg * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc. 332001f49Smrg * 432001f49Smrg * Permission to use, copy, modify, distribute, and sell this software and 532001f49Smrg * its documentation for any purpose is hereby granted without fee, provided 632001f49Smrg * that (i) the above copyright notices and this permission notice appear in 732001f49Smrg * all copies of the software and related documentation, and (ii) the name of 832001f49Smrg * Silicon Graphics may not be used in any advertising or 932001f49Smrg * publicity relating to the software without the specific, prior written 1032001f49Smrg * permission of Silicon Graphics. 1132001f49Smrg * 1232001f49Smrg * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF 1332001f49Smrg * ANY KIND, 1432001f49Smrg * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 1532001f49Smrg * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 1632001f49Smrg * 1732001f49Smrg * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR 1832001f49Smrg * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, 1932001f49Smrg * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 2032001f49Smrg * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 2132001f49Smrg * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 2232001f49Smrg * OF THIS SOFTWARE. 2332001f49Smrg */ 2432001f49Smrg 2532001f49Smrg#include <stdio.h> 2632001f49Smrg#include <stdlib.h> 2732001f49Smrg#include <string.h> 2832001f49Smrg#include <math.h> 2932001f49Smrg#include "glut_wrap.h" 3032001f49Smrg 3132001f49Smrg 3232001f49Smrg#define STEPCOUNT 40 3332001f49Smrg#define FALSE 0 3432001f49Smrg#define TRUE 1 3532001f49Smrg#define MAX(a, b) (((a) > (b)) ? (a) : (b)) 3632001f49Smrg#define MIN(a, b) (((a) < (b)) ? (a) : (b)) 3732001f49Smrg 3832001f49Smrg 3932001f49Smrgenum { 4032001f49Smrg OP_NOOP = 0, 4132001f49Smrg OP_STRETCH, 4232001f49Smrg OP_DRAWPOINT, 4332001f49Smrg OP_DRAWIMAGE 4432001f49Smrg}; 4532001f49Smrg 4632001f49Smrg 4732001f49Smrgtypedef struct _cRec { 4832001f49Smrg float x, y; 4932001f49Smrg} cRec; 5032001f49Smrg 5132001f49Smrgtypedef struct _vertexRec { 5232001f49Smrg float x, y; 5332001f49Smrg float dX, dY; 5432001f49Smrg float tX, tY; 5532001f49Smrg} vertexRec; 5632001f49Smrg 5732001f49Smrg 5832001f49Smrg#include "loadppm.c" 5932001f49Smrg 6032001f49SmrgGLenum doubleBuffer; 6132001f49Smrgint imageSizeX, imageSizeY; 6232001f49Smrgchar *fileName = 0; 6332001f49SmrgPPMImage *image; 6432001f49SmrgcRec cList[50]; 6532001f49SmrgvertexRec vList[5]; 6632001f49Smrgint cCount, cIndex[2], cStep; 6732001f49SmrgGLenum op = OP_NOOP; 6832001f49Smrg 6932001f49Smrg 7032001f49Smrgstatic void DrawImage(void) 7132001f49Smrg{ 7232001f49Smrg 7332001f49Smrg glRasterPos2i(0, 0); 7432001f49Smrg glDrawPixels(image->sizeX, image->sizeY, GL_RGB, GL_UNSIGNED_BYTE, 7532001f49Smrg image->data); 7632001f49Smrg 7732001f49Smrg glFlush(); 7832001f49Smrg if (doubleBuffer) { 7932001f49Smrg glutSwapBuffers(); 8032001f49Smrg } 8132001f49Smrg 8232001f49Smrg glRasterPos2i(0, 0); 8332001f49Smrg glDrawPixels(image->sizeX, image->sizeY, GL_RGB, GL_UNSIGNED_BYTE, 8432001f49Smrg image->data); 8532001f49Smrg} 8632001f49Smrg 8732001f49Smrgstatic void DrawPoint(void) 8832001f49Smrg{ 8932001f49Smrg int i; 9032001f49Smrg 9132001f49Smrg glColor3f(1.0, 0.0, 1.0); 9232001f49Smrg glPointSize(3.0); 9332001f49Smrg glBegin(GL_POINTS); 9432001f49Smrg for (i = 0; i < cCount; i++) { 9532001f49Smrg glVertex2f(cList[i].x, cList[i].y); 9632001f49Smrg } 9732001f49Smrg glEnd(); 9832001f49Smrg 9932001f49Smrg glFlush(); 10032001f49Smrg if (doubleBuffer) { 10132001f49Smrg glutSwapBuffers(); 10232001f49Smrg } 10332001f49Smrg} 10432001f49Smrg 10532001f49Smrgstatic void InitVList(void) 10632001f49Smrg{ 10732001f49Smrg 10832001f49Smrg vList[0].x = 0.0; 10932001f49Smrg vList[0].y = 0.0; 11032001f49Smrg vList[0].dX = 0.0; 11132001f49Smrg vList[0].dY = 0.0; 11232001f49Smrg vList[0].tX = 0.0; 11332001f49Smrg vList[0].tY = 0.0; 11432001f49Smrg 11532001f49Smrg vList[1].x = (float)imageSizeX; 11632001f49Smrg vList[1].y = 0.0; 11732001f49Smrg vList[1].dX = 0.0; 11832001f49Smrg vList[1].dY = 0.0; 11932001f49Smrg vList[1].tX = 1.0; 12032001f49Smrg vList[1].tY = 0.0; 12132001f49Smrg 12232001f49Smrg vList[2].x = (float)imageSizeX; 12332001f49Smrg vList[2].y = (float)imageSizeY; 12432001f49Smrg vList[2].dX = 0.0; 12532001f49Smrg vList[2].dY = 0.0; 12632001f49Smrg vList[2].tX = 1.0; 12732001f49Smrg vList[2].tY = 1.0; 12832001f49Smrg 12932001f49Smrg vList[3].x = 0.0; 13032001f49Smrg vList[3].y = (float)imageSizeY; 13132001f49Smrg vList[3].dX = 0.0; 13232001f49Smrg vList[3].dY = 0.0; 13332001f49Smrg vList[3].tX = 0.0; 13432001f49Smrg vList[3].tY = 1.0; 13532001f49Smrg 13632001f49Smrg vList[4].x = cList[0].x; 13732001f49Smrg vList[4].y = cList[0].y; 13832001f49Smrg vList[4].dX = (cList[1].x - cList[0].x) / STEPCOUNT; 13932001f49Smrg vList[4].dY = (cList[1].y - cList[0].y) / STEPCOUNT; 14032001f49Smrg vList[4].tX = cList[0].x / (float)imageSizeX; 14132001f49Smrg vList[4].tY = cList[0].y / (float)imageSizeY; 14232001f49Smrg} 14332001f49Smrg 14432001f49Smrgstatic void ScaleImage(int sizeX, int sizeY) 14532001f49Smrg{ 14632001f49Smrg GLubyte *buf; 14732001f49Smrg 14832001f49Smrg buf = (GLubyte *)malloc(3*sizeX*sizeY); 14932001f49Smrg gluScaleImage(GL_RGB, image->sizeX, image->sizeY, GL_UNSIGNED_BYTE, 15032001f49Smrg image->data, sizeX, sizeY, GL_UNSIGNED_BYTE, buf); 15132001f49Smrg free(image->data); 15232001f49Smrg image->data = buf; 15332001f49Smrg image->sizeX = sizeX; 15432001f49Smrg image->sizeY = sizeY; 15532001f49Smrg} 15632001f49Smrg 15732001f49Smrgstatic void SetPoint(int x, int y) 15832001f49Smrg{ 15932001f49Smrg 16032001f49Smrg cList[cCount].x = (float)x; 16132001f49Smrg cList[cCount].y = (float)y; 16232001f49Smrg cCount++; 16332001f49Smrg} 16432001f49Smrg 16532001f49Smrgstatic void Stretch(void) 16632001f49Smrg{ 16732001f49Smrg 16832001f49Smrg glBegin(GL_TRIANGLES); 16932001f49Smrg glTexCoord2f(vList[0].tX, vList[0].tY); 17032001f49Smrg glVertex2f(vList[0].x, vList[0].y); 17132001f49Smrg glTexCoord2f(vList[1].tX, vList[1].tY); 17232001f49Smrg glVertex2f(vList[1].x, vList[1].y); 17332001f49Smrg glTexCoord2f(vList[4].tX, vList[4].tY); 17432001f49Smrg glVertex2f(vList[4].x, vList[4].y); 17532001f49Smrg glEnd(); 17632001f49Smrg 17732001f49Smrg glBegin(GL_TRIANGLES); 17832001f49Smrg glTexCoord2f(vList[1].tX, vList[1].tY); 17932001f49Smrg glVertex2f(vList[1].x, vList[1].y); 18032001f49Smrg glTexCoord2f(vList[2].tX, vList[2].tY); 18132001f49Smrg glVertex2f(vList[2].x, vList[2].y); 18232001f49Smrg glTexCoord2f(vList[4].tX, vList[4].tY); 18332001f49Smrg glVertex2f(vList[4].x, vList[4].y); 18432001f49Smrg glEnd(); 18532001f49Smrg 18632001f49Smrg glBegin(GL_TRIANGLES); 18732001f49Smrg glTexCoord2f(vList[2].tX, vList[2].tY); 18832001f49Smrg glVertex2f(vList[2].x, vList[2].y); 18932001f49Smrg glTexCoord2f(vList[3].tX, vList[3].tY); 19032001f49Smrg glVertex2f(vList[3].x, vList[3].y); 19132001f49Smrg glTexCoord2f(vList[4].tX, vList[4].tY); 19232001f49Smrg glVertex2f(vList[4].x, vList[4].y); 19332001f49Smrg glEnd(); 19432001f49Smrg 19532001f49Smrg glBegin(GL_TRIANGLES); 19632001f49Smrg glTexCoord2f(vList[3].tX, vList[3].tY); 19732001f49Smrg glVertex2f(vList[3].x, vList[3].y); 19832001f49Smrg glTexCoord2f(vList[0].tX, vList[0].tY); 19932001f49Smrg glVertex2f(vList[0].x, vList[0].y); 20032001f49Smrg glTexCoord2f(vList[4].tX, vList[4].tY); 20132001f49Smrg glVertex2f(vList[4].x, vList[4].y); 20232001f49Smrg glEnd(); 20332001f49Smrg 20432001f49Smrg glFlush(); 20532001f49Smrg if (doubleBuffer) { 20632001f49Smrg glutSwapBuffers(); 20732001f49Smrg } 20832001f49Smrg 20932001f49Smrg if (++cStep < STEPCOUNT) { 21032001f49Smrg vList[4].x += vList[4].dX; 21132001f49Smrg vList[4].y += vList[4].dY; 21232001f49Smrg } else { 21332001f49Smrg cIndex[0] = cIndex[1]; 21432001f49Smrg cIndex[1] = cIndex[1] + 1; 21532001f49Smrg if (cIndex[1] == cCount) { 21632001f49Smrg cIndex[1] = 0; 21732001f49Smrg } 21832001f49Smrg vList[4].dX = (cList[cIndex[1]].x - cList[cIndex[0]].x) / STEPCOUNT; 21932001f49Smrg vList[4].dY = (cList[cIndex[1]].y - cList[cIndex[0]].y) / STEPCOUNT; 22032001f49Smrg cStep = 0; 22132001f49Smrg } 22232001f49Smrg} 22332001f49Smrg 22432001f49Smrgstatic void Key(unsigned char key, int x, int y) 22532001f49Smrg{ 22632001f49Smrg 22732001f49Smrg switch (key) { 22832001f49Smrg case 27: 22932001f49Smrg free(image->data); 23032001f49Smrg exit(1); 23132001f49Smrg case 32: 23232001f49Smrg if (cCount > 1) { 23332001f49Smrg InitVList(); 23432001f49Smrg cIndex[0] = 0; 23532001f49Smrg cIndex[1] = 1; 23632001f49Smrg cStep = 0; 23732001f49Smrg glEnable(GL_TEXTURE_2D); 23832001f49Smrg op = OP_STRETCH; 23932001f49Smrg } 24032001f49Smrg break; 24132001f49Smrg default: 24232001f49Smrg return; 24332001f49Smrg } 24432001f49Smrg 24532001f49Smrg glutPostRedisplay(); 24632001f49Smrg} 24732001f49Smrg 24832001f49Smrgstatic void Mouse(int button, int state, int mouseX, int mouseY) 24932001f49Smrg{ 25032001f49Smrg 25132001f49Smrg if (state != GLUT_DOWN) 25232001f49Smrg return; 25332001f49Smrg 25432001f49Smrg if (op == OP_STRETCH) { 25532001f49Smrg glDisable(GL_TEXTURE_2D); 25632001f49Smrg cCount = 0; 25732001f49Smrg op = OP_DRAWIMAGE; 25832001f49Smrg } else { 25932001f49Smrg SetPoint(mouseX, imageSizeY-mouseY); 26032001f49Smrg op = OP_DRAWPOINT; 26132001f49Smrg } 26232001f49Smrg 26332001f49Smrg glutPostRedisplay(); 26432001f49Smrg} 26532001f49Smrg 26632001f49Smrgstatic void Animate(void) 26732001f49Smrg{ 26832001f49Smrg static double t0 = -1.; 26932001f49Smrg double t, dt; 27032001f49Smrg t = glutGet(GLUT_ELAPSED_TIME) / 1000.; 27132001f49Smrg if (t0 < 0.) 27232001f49Smrg t0 = t; 27332001f49Smrg dt = t - t0; 27432001f49Smrg 27532001f49Smrg if (dt < 1./60.) 27632001f49Smrg return; 27732001f49Smrg 27832001f49Smrg t0 = t; 27932001f49Smrg 28032001f49Smrg switch (op) { 28132001f49Smrg case OP_STRETCH: 28232001f49Smrg Stretch(); 28332001f49Smrg break; 28432001f49Smrg case OP_DRAWPOINT: 28532001f49Smrg DrawPoint(); 28632001f49Smrg break; 28732001f49Smrg case OP_DRAWIMAGE: 28832001f49Smrg DrawImage(); 28932001f49Smrg break; 29032001f49Smrg default: 29132001f49Smrg break; 29232001f49Smrg } 29332001f49Smrg} 29432001f49Smrg 29532001f49Smrgstatic GLenum Args(int argc, char **argv) 29632001f49Smrg{ 29732001f49Smrg GLint i; 29832001f49Smrg 29932001f49Smrg doubleBuffer = GL_TRUE; 30032001f49Smrg 30132001f49Smrg for (i = 1; i < argc; i++) { 30232001f49Smrg if (strcmp(argv[i], "-sb") == 0) { 30332001f49Smrg doubleBuffer = GL_FALSE; 30432001f49Smrg } else if (strcmp(argv[i], "-db") == 0) { 30532001f49Smrg doubleBuffer = GL_TRUE; 30632001f49Smrg } else if (strcmp(argv[i], "-f") == 0) { 30732001f49Smrg if (i+1 >= argc || argv[i+1][0] == '-') { 30832001f49Smrg printf("-f (No file name).\n"); 30932001f49Smrg return GL_FALSE; 31032001f49Smrg } else { 31132001f49Smrg fileName = argv[++i]; 31232001f49Smrg } 31332001f49Smrg } else { 31432001f49Smrg printf("%s (Bad option).\n", argv[i]); 31532001f49Smrg return GL_FALSE; 31632001f49Smrg } 31732001f49Smrg } 31832001f49Smrg return GL_TRUE; 31932001f49Smrg} 32032001f49Smrg 32132001f49Smrg#if !defined(GLUTCALLBACK) 32232001f49Smrg#define GLUTCALLBACK 32332001f49Smrg#endif 32432001f49Smrg 32532001f49Smrgstatic void GLUTCALLBACK glut_post_redisplay_p(void) 32632001f49Smrg{ 32732001f49Smrg glutPostRedisplay(); 32832001f49Smrg} 32932001f49Smrg 33032001f49Smrgint main(int argc, char **argv) 33132001f49Smrg{ 33232001f49Smrg GLenum type; 33332001f49Smrg 33432001f49Smrg glutInit(&argc, argv); 33532001f49Smrg 33632001f49Smrg if (Args(argc, argv) == GL_FALSE) { 33732001f49Smrg exit(1); 33832001f49Smrg } 33932001f49Smrg 34032001f49Smrg if (fileName == 0) { 34132001f49Smrg printf("No image file.\n"); 34232001f49Smrg exit(1); 34332001f49Smrg } 34432001f49Smrg 34532001f49Smrg image = LoadPPM(fileName); 34632001f49Smrg 34732001f49Smrg /* changed powf and logf to pow and log -Brian */ 34832001f49Smrg imageSizeX = (int)pow(2.0, (float)((int)(log(image->sizeX)/log(2.0)))); 34932001f49Smrg imageSizeY = (int)pow(2.0, (float)((int)(log(image->sizeY)/log(2.0)))); 35032001f49Smrg 35132001f49Smrg glutInitWindowPosition(0, 0); glutInitWindowSize( imageSizeX, imageSizeY); 35232001f49Smrg 35332001f49Smrg type = GLUT_RGB; 35432001f49Smrg type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE; 35532001f49Smrg glutInitDisplayMode(type); 35632001f49Smrg 35732001f49Smrg if (glutCreateWindow("Stretch") == GL_FALSE) { 35832001f49Smrg exit(1); 35932001f49Smrg } 36032001f49Smrg 36132001f49Smrg glViewport(0, 0, imageSizeX, imageSizeY); 36232001f49Smrg gluOrtho2D(0, imageSizeX, 0, imageSizeY); 36332001f49Smrg glClearColor(0.0, 0.0, 0.0, 0.0); 36432001f49Smrg 36532001f49Smrg glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 36632001f49Smrg glPixelStorei(GL_PACK_ALIGNMENT, 1); 36732001f49Smrg 36832001f49Smrg ScaleImage(imageSizeX, imageSizeY); 36932001f49Smrg 37032001f49Smrg glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); 37132001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); 37232001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); 37332001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 37432001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 37532001f49Smrg glTexImage2D(GL_TEXTURE_2D, 0, 3, image->sizeX, image->sizeY, 0, 37632001f49Smrg GL_RGB, GL_UNSIGNED_BYTE, (unsigned char *)image->data); 37732001f49Smrg 37832001f49Smrg cCount = 0; 37932001f49Smrg cIndex[0] = 0; 38032001f49Smrg cIndex[1] = 0; 38132001f49Smrg cStep = 0; 38232001f49Smrg op = OP_DRAWIMAGE; 38332001f49Smrg 38432001f49Smrg glutKeyboardFunc(Key); 38532001f49Smrg glutMouseFunc(Mouse); 38632001f49Smrg glutDisplayFunc(Animate); 38732001f49Smrg glutIdleFunc(glut_post_redisplay_p); 38832001f49Smrg glutMainLoop(); 38932001f49Smrg return 0; 39032001f49Smrg} 391