📄 ffglut.cpp
字号:
void drwstr(R x,R y,char* format, ...) { va_list args; char *s,buffer[1024]; va_start(args,format); vsnprintf(buffer,1024,format,args); va_end(args); } */void plot(double xx,double yy,const char *cmm,int font){ glRasterPos2f(xx,yy); float x[4]; glGetFloatv(GL_CURRENT_RASTER_POSITION,x); if((debug > 10)) cout<<"avant x : "<<x[0]<<" y : "<<x[1]<<" z : "<<x[2]<< " " << xx <<" " << yy << endl; /* #define GLUT_BITMAP_9_BY_15((void*)2) #define GLUT_BITMAP_8_BY_13((void*)3) #define GLUT_BITMAP_TIMES_ROMAN_10((void*)4) #define GLUT_BITMAP_TIMES_ROMAN_24((void*)5) #define GLUT_BITMAP_HELVETICA_10((void*)6) #define GLUT_BITMAP_HELVETICA_12((void*)7) #define GLUT_BITMAP_HELVETICA_18((void*)8) */ void * glut_font=GLUT_BITMAP_TIMES_ROMAN_10; switch (font) { case 0: glut_font=GLUT_STROKE_ROMAN;break; case 1: glut_font=GLUT_STROKE_MONO_ROMAN;break; case 2: glut_font=GLUT_BITMAP_9_BY_15;break; case 3: glut_font=GLUT_BITMAP_8_BY_13;break; case 4: glut_font=GLUT_BITMAP_TIMES_ROMAN_10;break; case 5: glut_font=GLUT_BITMAP_TIMES_ROMAN_24;break; case 6: glut_font=GLUT_BITMAP_HELVETICA_10;break; case 7: glut_font=GLUT_BITMAP_HELVETICA_12;break; case 8: glut_font=GLUT_BITMAP_HELVETICA_18;break; } for (const char *s=cmm; *s; s++) {if((debug > 10)) cout << *s ; glutBitmapCharacter(glut_font,*s); } if((debug > 10)) cout << " ;;; " <<endl;}void plot(double x,double y,double i,int font){ char buf[24]; snprintf(buf,24,"%g",i,font); plot(x,y,buf);}void hsvToRgb (float h, float s, float v, float & r, float & g, float & b){ int i; float aa, bb, cc, f; if (s == 0) /* Grayscale */ r = g = b = v; else { if (h == 1.0) h = 0; h *= 6.0; i = int(h); f = h - i; aa = v * (1 - s); bb = v * (1 - (s * f)); cc = v * (1 - (s * (1 - f))); switch (i) { case 0: r = v; g = cc; b = aa; break; case 1: r = bb; g = v; b = aa; break; case 2: r = aa; g = v; b = cc; break; case 3: r = aa; g = bb; b = v; break; case 4: r = cc; g = aa; b = v; break; case 5: r = v; g = aa; b = bb; break; } }}void ThePlot::DrawIsoT(const R2 Pt[3],const R ff[3],const R * Viso,int NbIso, R rapz){ glBegin(GL_LINES); R2 PQ[5]; //int NbIso = Viso.N(); for(int l=0;l< NbIso;l++) /* loop on the level curves */ { R xf = Viso[l]; int im=0; for(int i=0;i<3;i++) // for the 3 edges { int j = (i+1)%3; R fi=(ff[i]); R fj=(ff[j]); if(((fi<=xf)&&(fj>=xf))||((fi>=xf)&&(fj<=xf))) { if (Abs(fi-fj)<=0.1e-10) /* one side must be drawn */ { color(l+4); glVertex3f(Pt[i].x, Pt[i].y,xf*rapz); glVertex3f(Pt[j].x, Pt[j].y,xf*rapz); //MoveTo(Pt[i]); //LineTo(Pt[j]); } else { R xlam=(fi-xf)/(fi-fj); PQ[im++] = Pt[i] * (1.F-xlam) + Pt[j]* xlam; } } } if (im>=2) /* draw one segment */ { color(l+4); //MoveTo(PQ[0]); //LineTo(PQ[1]); glVertex3f(PQ[0].x, PQ[0].y,xf*rapz); glVertex3f(PQ[1].x, PQ[1].y,xf*rapz); } } glEnd(); } void ThePlot::DrawIsoTfill(const R2 Pt[3],const R ff[3],const R * Viso,int NbIso, R rapz){ R2 PQ[10]; R z[10]; R eps= (Viso[NbIso-1]-Viso[0])*1e-6; for(int l=1;l< NbIso;l++) // loop on the level curves { R xfb = Viso[l-1]; R xfh = Viso[l]; assert(xfb < xfh); int im=0; for(int i=0;i<3;i++) // for the 3 edges { int j=(i+1)%3; R fi=(ff[i]); R fj=(ff[j]); R xxfb = xfb; R xxfh = xfh; if (fj<fi ) Exchange(xxfb,xxfh); R xf = xxfb; if(((fi<=xf)&&(fj>=xf))||((fi>=xf)&&(fj<=xf))) { if (Abs(fi-fj)>=0.1e-20) { R xlam=(fi-xf)/(fi-fj); z[im] = ff[i] * (1.F-xlam) + ff[j]* xlam; PQ[im++] = Pt[i] * (1.F-xlam) + Pt[j]* xlam; } } xf = xxfh; if(((fi<=xf)&&(fj>=xf))||((fi>=xf)&&(fj<=xf))) { if (Abs(fi-fj)>=0.1e-20) { R xlam=(fi-xf)/(fi-fj); z[im] = ff[i] * (1.F-xlam) + ff[j]* xlam; PQ[im++] = Pt[i] * (1.F-xlam) + Pt[j]* xlam; } } if ( xfb-eps <=fj && fj <= xfh+eps) z[im]=ff[j],PQ[im++] = Pt[j]; } if (im>2) { color(l+4); R3 P[10]; for(int i=0;i<im;++i) P[i]= R3(PQ[i].x,PQ[i].y,z[i]*rapz); R3 N(R3(P[0],P[1])^R3(P[0],P[2])); N /= N.norme(); if(N.z<0) N = -N; glNormal3d(N.x,N.y,N.z); glBegin(GL_POLYGON); //SetColor((xfb+xfh)/2); for (int i=0;i<im;i++) {// if((debug > 10)) cout << i << " \t : " << PQ[i].x << " " << PQ[i].y << " " << z[i]*rapz << endl; glVertex3f(P[i].x, P[i].y,P[i].z); } glEnd(); } }} bool WindowDump(int width,int height){ int i,j; FILE *fptr; static int counter = 0; char fname[32]; unsigned char *image; /* Allocate our buffer for the image */ if ((image = new unsigned char[3*width*height]) == NULL) { fprintf(stderr,"WindowDump - Failed to allocate memory for image\n"); return(false); } /* Open the file */ sprintf(fname,"ffglut_%04d.ppm",counter); if ((fptr = fopen(fname, MODE_WRITE_BINARY)) == NULL) { fprintf(stderr,"WindowDump - Failed to open file for window dump\n"); return(false); } if((debug > 10)) cout << " WindowDump in " << fname << endl; /* Copy the image into our buffer */ glReadBuffer(GL_FRONT); glReadPixels(0,0,width,height,GL_RGB,GL_UNSIGNED_BYTE,image); /* Write the PPM file */ fprintf(fptr,"P6\n%d %d\n255\n",width,height); for (j=height-1;j>=0;j--) { for (i=0;i<width;i++) { fputc(image[3*j*width+3*i+0],fptr); fputc(image[3*j*width+3*i+1],fptr); fputc(image[3*j*width+3*i+2],fptr); } } fclose(fptr); delete [] image; counter++; return(true);}void Clean() { glClearColor(1.0, 1.0, 1.0, 0.0); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );}static void Reshape( int width, int height ){ OneWindow * win=CurrentWin(); if(win) win->resize(width,height); glutPostRedisplay();}void Display(void){ OneWindow * win=CurrentWin(); if(win) { /* if (win->stereo) { ffassert(0); glClearColor(1.0, 1.0, 1.0, 0.0); glDrawBuffer(GL_BACK_RIGHT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); global->SetView(-1); glCallList(TheDrawList); glClearColor(1.0, 1.0, 1.0, 0.0); glDrawBuffer(GL_BACK_LEFT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); global->SetView(+1); glCallList(TheDrawList); //win->Display(); glFlush(); glutSwapBuffers(); } else */ { Clean(); win->Display(); glFlush(); glutSwapBuffers(); if ( win->windowdump) WindowDump(win->width,win->height); win->windowdump=false; } } if(!win->theplot->wait) SendForNextPlot(); if(!NoMorePlotTilte &&NoMorePlot) { NoMorePlotTilte=true; glutSetWindowTitle("FreeFem++ / Program ended; enter ESC to exit)"); }}static void Mouse( int button,int state,int x,int y ){ // state up or down OneWindow * win=CurrentWin(); if(win) { if(win && state == GLUT_DOWN) { win->xold=x,win->yold=y;return;} win->phi += (y-win->yold)/(2.*180.); win->theta -= (x-win->xold)/(2*180.); glutPostRedisplay(); }}static void MotionMouse(int x,int y ){ OneWindow * win=CurrentWin(); if(win) { win->phi += (y-win->yold)/(2.*180.); win->theta -= (x-win->xold)/(2*180.); win->xold=x; win->yold=y; glutPostRedisplay(); }}static void Key( unsigned char key, int x, int y ){ OneWindow * win=CurrentWin(); switch (key) { case 27: // esc char Fin(0); break; case 'w': if(win) win->windowdump=true; break; case 'l': win->withlight = !win->withlight; break; case '?' : if(win) win->help=true; case '+': win->zoom(x,y,0.7); win->coef_dist /= 1.2; break; case '-': win->zoom(x,y,1./0.7); win->coef_dist *= 1.2; break; case '3': win->plotdim=win->plotdim==2?3:2; break; /* case '2': win->plotdim=2; break; */ case '=': win->DefaultView(); break; case 'f': win->theplot->fill = ! win->theplot->fill ; break; case '@': win->dtheta = win->dtheta ? 0 : pi/1800.; break; case 'b': win->theplot->grey = ! win->theplot->grey ; break; case 'g': win->theplot->grey = ! win->theplot->grey ; break; case 'v': win->theplot->value = ! win->theplot->value ; break; case 'm': win->theplot->drawmeshes = ! win->theplot->drawmeshes ; break; case 'B': win->theplot->drawborder = ! win->theplot->drawborder ; break; case 'H': win->rapz *= 1.2; break; case 'h': win->rapz /= 1.2; break; case 'p': if(win->icurrentPlot != win->lplots.begin()) win->set(*--win->icurrentPlot); break; case 'a': win->theplot->coeff/= 1.2; break; case 'A': win->theplot->coeff*= 1.2; break; case 'z': if(win->focal < M_PI/1.2 ) { win->coef_dist*=sin(win->focal*1.2/2)/sin(win->focal/2); win->focal *=1.2; } break; case 'Z': if(win->focal > 1e-5) { win->coef_dist*=sin(win->focal/1.2/2)/sin(win->focal/2); win->focal /=1.2; } break; case '\r': case '\n': { list<ThePlot*>::iterator ic = win->icurrentPlot; if(++ic == win->lplots.end()) // last plot -> try new one SendForNextPlot(); else win->set(*++win->icurrentPlot); break; } default: if((debug > 10)) cout << " Key Character " << (int) key << " " << key << endl; } glutPostRedisplay();}void SpecialKey(int key, int x, int y){ OneWindow * win=CurrentWin(); if(win) { // if((debug > 10)) cout << " SpecialKey " << key << " " << x << " " << y << " : "; R dx(0),dy(0); switch (key) { case GLUT_KEY_LEFT: dx = -1; break; case GLUT_KEY_RIGHT: dx = +1; break; case GLUT_KEY_DOWN: dy = -1; break; case GLUT_KEY_UP: dy = +1; break; } // calcul du deplacement de xm,ym,zm; // if((debug > 10)) cout << " " << dx << " " << dy << endl; win->MoveXView(dx,dy); glutPostRedisplay(); }}void LauchNextRead(){ if(!NoMorePlot) { inThreadRead=true; tidRead = Thread::Start(&ThreadRead,(void *) datafile); }}void WaitNextRead(){ if( inThreadRead ) { assert(tidRead!=0); Thread::Wait(tidRead); tidRead =0; inThreadRead=false;; }}//void * ThreadRead(void *fd)THREADFUNC(ThreadRead,fd){ int err=0; assert(nextPlot==0); // MutexNextPlot.WAIT(); err=ReadOnePlot((FILE*)fd); // MutexNextPlot.Free(); if(debug>1) cout << " We Read a plot : " << kread << " " << nextPlot << " " << err << endl; if(err<0) NoMorePlot=true; Thread::Exit();}int main(int argc, char** argv){ glutInit(&argc, argv); bool stereo=false; bool fullscreen = false; if(stereo) glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_STEREO); else glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ); if(argc>2) { if( strcmp(argv[1],"-nv")==0) debug=0; if( strcmp(argv[1],"-v")==0) debug=2,verbosity=2; if( strcmp(argv[1],"-vv")==0) debug=5,verbosity=2; if( strcmp(argv[1],"-vvv")==0) debug=10, verbosity=1000; } if(debug>1) cout << " mode read = " << MODE_READ_BINARY << endl; datafile =0;; if(argc>1 && *argv[argc-1] != '-' ) { datafile=fopen(argv[argc-1], "r"); cout << " fopen :" << argv[argc-1] << " " <<datafile << endl; } if(datafile==0) datafile=stdin; if ( !datafile){ cerr<< " Erreur fdopen stdin in binary " << endl; Fin(1); } int err=ReadOnePlot(datafile); if(err) {cout << "Err ReadOnePlot " << err << endl; Fin(1);} if(kread==0) { cout << " Error: no graphic data " << endl; Fin(1); } if(debug>1) cout << "on a lue le premier plot next plot: " << nextPlot << endl; int Height = 512; int Width = 512*3/2; glutInitWindowSize(Width , Height); glutInitWindowPosition(100, 100); string titre = "FreeFem++: type return key to proceed (or ? for help on other)"; glutCreateWindow(titre.c_str()); glutPushWindow(); if (fullscreen) glutFullScreen(); AllWindows[glutGetWindow()]=new OneWindow(Width , Height,currentPlot); TryNewPlot(); glDisable(GL_DEPTH_TEST); glutReshapeFunc( Reshape ); // pour changement de fenetre glutKeyboardFunc( Key ); // pour les evenements clavier glutSpecialFunc(SpecialKey); glutMouseFunc(Mouse); // pour les evenements sourie glutMotionFunc(MotionMouse); // les mouvements de la sourie glutDisplayFunc( Display ); // l'affichage glutMainLoop(); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -