#include "main.h" #include #include #include int mainMenu; int displayMenu; const int maxLines = 100; const int lengthLines = 100; float sourceLines[maxLines][lengthLines][2]; float destLines[maxLines][lengthLines][2]; int sizeLines[maxLines]; // indices for adding new lines int nextLine=0; bool inLine=false; // indices for editing lines int selectPoint=-1; int selectLine=-1; int selectImage=-1; // display colors float linedisplay[3]={0,0,1}; float pointdisplay[3]={1,0,0}; enum { M_QUIT = 0, M_HELP, M_DATA_READ, M_DATA_SAVE, M_DISP_ALL, M_DISP_CURRENT, M_DISP_NEXT, M_NEWLINE, M_SELECT, M_DELETELINE }; bool addMode=true; int displayMode=M_DISP_ALL; int windowWidth; int windowHeight; int imageWidth; int imageHeight; Image* sourceImage = NULL; Image* destImage = NULL; void display(); void sourceDisplay(); void destDisplay(); void reshape(int width, int height); void keyboard(unsigned char key, int x, int y); void mouse(int button, int state, int x, int y); void arrowKeys(int key, int x, int y); void addPoint(int x, int y); void choosePoint(int x, int y); void motion(int x, int y); int imagePosX(int x); int imagePosY(int y); int windowPosX(int image, int x); int windowPosY(int image, int y); int imageNumber(int x); void drawLines(); void menu_func(int value); void make_menu(); int main (int argc, char** argv) { // read in the input files sourceImage= new Image("source.bmp"); destImage = new Image("destination.bmp"); if ( (sourceImage->getChannels() != destImage->getChannels()) || (sourceImage->getWidth() != destImage->getWidth()) || (sourceImage->getHeight() != destImage->getHeight()) ) { cout << "Input images must be same size and number of channels." << endl; exit(0); } imageWidth = sourceImage->getWidth(); imageHeight = sourceImage->getHeight(); windowWidth=2*imageWidth+3; windowHeight=imageHeight+2; // set up the window glutInit(&argc, &argv[0]); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); // set up main window glutInitWindowPosition(100,100); glutInitWindowSize(windowWidth, windowHeight); glutCreateWindow("hmc cs155 morph tool"); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMouseFunc(mouse); glutMotionFunc(motion); glutSpecialFunc(arrowKeys); // set up menus make_menu(); // set up opengl glClearColor(0.0,0.0,0.0,0.0); glDisable(GL_DEPTH_TEST); // wait for something to happen glutMainLoop(); return 0; } void display () { // check if there have been any openGL problems GLenum errCode = glGetError(); if (errCode != GL_NO_ERROR) { const GLubyte* errString = gluErrorString(errCode); cout << "OpenGL error: " << errString << endl; } // clear the frame buffer glClear(GL_COLOR_BUFFER_BIT); // draw the image if (sourceImage) { sourceDisplay(); } if (destImage) { destDisplay(); } // draw lines drawLines(); // swap buffers glutSwapBuffers(); } void sourceDisplay() { // we are drawing the image to the left half of the window (with a one pixel border) glRasterPos2i(1,1); if (sourceImage) { sourceImage->glDrawPixelsWrapper(); } } void destDisplay() { glRasterPos2i(2+imageWidth, 1); if (destImage) { destImage->glDrawPixelsWrapper(); } } void drawLines() { // draw source lines if (selectLine<-1 || selectPoint<-1 || selectImage <-1) cout << "problem: " << selectPoint << " " << selectLine << " " << selectImage << endl; glColor3f(linedisplay[0],linedisplay[1],linedisplay[2]); if (displayMode == M_DISP_ALL) { for (int i=0;i=2) { glBegin(GL_LINE_STRIP); for (int j=0; j=2) { glBegin(GL_LINE_STRIP); for (int j=0; j=2) { glBegin(GL_LINE_STRIP); for (int j=0; j=2) { glBegin(GL_LINE_STRIP); for (int j=0; j=imageWidth || sourceLines[selectLine][i][0]<0 || sourceLines[selectLine][i][1]>=imageHeight || sourceLines[selectLine][i][1]<0) ok=false; } else { destLines[selectLine][i][0] += dx; destLines[selectLine][i][1] += dy; if (destLines[selectLine][i][0]>=imageWidth || destLines[selectLine][i][0]<0 || destLines[selectLine][i][1]>=imageHeight || destLines[selectLine][i][1]<0) ok=false; } } if (!ok) { for (int i=0; i> linedisplay[0]; cin >> linedisplay[1]; cin >> linedisplay[2]; cin >> pointdisplay[0]; cin >> pointdisplay[1]; cin >> pointdisplay[2]; break; } } void mouse(int button, int state, int x, int y) { if( x==imageWidth+2 || button!=GLUT_LEFT_BUTTON || state == GLUT_UP) return; int control = glutGetModifiers(); //cout << "Inline: " << inLine << endl; if (control > 0) { // we're adding a point if (!inLine) { menu_func(M_NEWLINE); //cout << "Inline switched: " << inLine << endl; } addPoint(x,y); } else { if (inLine) { menu_func(M_SELECT); //cout << "Inline switched: " << inLine << endl; } choosePoint(x,y); } /* if (state == GLUT_DOWN && control>0) { if (inLine) menu_func(M_SELECT); choosePoint(x,y); } else if (state == GLUT_DOWN && control == 0) { if (!inLine) menu_func(M_NEWLINE); } else if (state == GLUT_UP && inLine) { addPoint(x,y); } */ } void motion(int x, int y) { int yprime=windowHeight-1-y; if (selectImage==-1) return; if (selectImage==0) { sourceLines[selectLine][selectPoint][0]=imagePosX(x); sourceLines[selectLine][selectPoint][1]=imagePosY(yprime); } else { destLines[selectLine][selectPoint][0]=imagePosX(x); destLines[selectLine][selectPoint][1]=imagePosY(yprime); } glutPostRedisplay(); } void addPoint(int x, int y) { if (selectLine==-1) { // we're starting a new line selectLine=nextLine; cout << "Starting line " << selectLine << endl; nextLine++; if (selectLine>=maxLines) { cout << "Sorry, you've used the max number of lines." << endl; selectLine=-1; selectImage=-1; selectPoint=-1; return; } sizeLines[selectLine]=0; selectImage=imageNumber(x); } else if (imageNumber(x)!=selectImage) return; // add on to current line selectPoint=sizeLines[selectLine]; if (selectPoint >= lengthLines) { cout << "Sorry, you've reached the maximum length for a line." << endl; selectLine=-1; selectImage=-1; selectPoint=-1; inLine=false; return; } //cout << "Adding point " << selectPoint << " to line " << selectLine << " in image " << selectImage << endl; // add x coordinate int xpos=imagePosX(x); sourceLines[selectLine][selectPoint][0]=xpos; destLines[selectLine][selectPoint][0]=xpos; // add y coordinate int ypos=imagePosY(windowHeight-1-y); sourceLines[selectLine][selectPoint][1]=ypos; destLines[selectLine][selectPoint][1]=ypos; //update length of current line sizeLines[selectLine]++; // redraw glutPostRedisplay(); } void choosePoint(int x,int y) { int currDistanceSquared, newDistanceSquared; // if we were adding to a line we need to end it if (inLine) menu_func(M_SELECT); if (nextLine==0) //there is nothing to look for return; // find closest point selectImage=imageNumber(x); int xpos=imagePosX(x); int ypos=imagePosY(windowHeight-y); currDistanceSquared =imageWidth*imageWidth+imageHeight*imageHeight; if (displayMode == M_DISP_ALL) { for (int i=0;i500) { // not a good selection selectImage=-1; selectLine=-1; selectPoint=-1; cout << "There isn't anything nearby." << endl; } glutPostRedisplay(); return; } int imagePosX(int x) { int xpos=x; if (xpos>=imageWidth+1) xpos-=(imageWidth+1); if (xpos<=0) return 0; xpos -=1; // take off left boundary if (xpos=imageHeight) ypos=imageHeight-1; return ypos; } int windowPosX(int image, int x) { if (image==0) return x+1; return imageWidth+x+2; } int windowPosY(int image, int y) { return y+1; } int imageNumber(int x) { if (x<2+imageWidth) return 0; else return 1; } void make_menu () { displayMenu = glutCreateMenu(menu_func); glutAddMenuEntry("All", M_DISP_ALL); glutAddMenuEntry("Selected", M_DISP_CURRENT); glutAddMenuEntry("Next ", M_DISP_NEXT); mainMenu = glutCreateMenu(menu_func); glutAddMenuEntry( "Read data", M_DATA_READ); glutAddMenuEntry( "Save data", M_DATA_SAVE); glutAddSubMenu( "Display", displayMenu); glutAddMenuEntry( "Delete selected line ", M_DELETELINE); glutAddMenuEntry( "End current line", M_SELECT); glutAddMenuEntry( "Start new line ", M_NEWLINE); glutAddMenuEntry( "Quit", M_QUIT); glutAddMenuEntry( "Help", M_HELP); glutAttachMenu(GLUT_RIGHT_BUTTON); return; } void menu_func (int value) { char answer; bool done; int i; switch (value) { case M_QUIT: cout << "Do you want to save your data?" << endl; cin >> answer; if (answer=='y') menu_func(M_DATA_SAVE); exit(0); break; case M_DATA_READ: { if (nextLine>0) { cout << "You'll lose all current data. Do you want to continue? (Y/N)"; cin >> answer; if (answer!='y' && answer !='Y') { cout << "OK, we'll forget you asked." << endl; break; } } fstream ifile("morph.dat", fstream::in); ifile >> nextLine; for (int i=0;i> sizeLines[i]; for (int j=0;j> sourceLines[i][j][0]; ifile >> sourceLines[i][j][1]; ifile >> destLines[i][j][0]; ifile >> destLines[i][j][1]; } } ifile.close(); glutPostRedisplay(); cout << "Done." << endl; displayMode = M_DISP_ALL; break; } case M_DATA_SAVE: { if (nextLine == 0 ) { cout << "You need to enter some lines first." << endl; break; } cout << "Warning: any data stored in morph.dat will be lost." << endl; cout << "Do you want to continue? (Y>N) "; cin >> answer; if (answer != 'y' && answer != 'Y') { cout << "OK. We'll forget you asked." << endl; break; } fstream ofile("morph.dat", fstream::out); // TODO: Test that file is ok. ofile << nextLine << endl; for (int i=0;i=nextLine) selectLine=0; if (sizeLines[selectLine]!=0) done=true; else selectLine++; } if (i!=selectLine) { selectImage=0; selectPoint=0; } break; case M_NEWLINE: if (inLine) { if (selectLine != -1) { if (sizeLines[selectLine] < 2) { // we're going to discard current line nextLine--; cout << "Discarding line " << selectLine << endl; } } } // select line/image/point will be reset for new line selectLine=-1; selectImage=-1; selectPoint=-1; inLine=true; break; case M_SELECT: if (inLine && selectLine!=-1) { // are we keeping the last line? if (sizeLines[selectLine] < 2) { // we're going to discard current line nextLine--; cout << "Discarding line " << selectLine << endl; } else { cout << "Ending line " << selectLine << endl; } } selectLine=-1; selectImage=-1; selectPoint=-1; inLine=false; break; } case M_DELETELINE: if (selectLine == -1) { cout << "You need to select a line first." << endl; } else { cout << "Are you sure you want to delete the selected line? (Y/N)"; cin >> answer; if (answer=='y' || answer=='Y') { sizeLines[selectLine]=0; selectLine=-1; selectImage=-1; selectPoint=-1; inLine=false; displayMode = M_DISP_ALL; } } break; case M_HELP: cout << "Left mouse selects and drags a point." << endl; cout << "Control left mouse enters new point." << endl; cout << "Arrows move selected line (to select line, select a point on the line)." << endl; cout << "Right mouse shows menu of other options." << endl; }// end switch glutPostRedisplay(); }