diff options
Diffstat (limited to 'Build/source/utils/asymptote/glrender.cc')
-rw-r--r-- | Build/source/utils/asymptote/glrender.cc | 280 |
1 files changed, 146 insertions, 134 deletions
diff --git a/Build/source/utils/asymptote/glrender.cc b/Build/source/utils/asymptote/glrender.cc index 5979aa708ba..8dec9d0405c 100644 --- a/Build/source/utils/asymptote/glrender.cc +++ b/Build/source/utils/asymptote/glrender.cc @@ -48,6 +48,7 @@ using camp::transform; using camp::pair; using camp::triple; using vm::array; +using vm::read; using camp::bbox3; using settings::getSetting; using settings::Setting; @@ -111,7 +112,8 @@ bool queueExport=false; bool antialias; int x0,y0; -int mod; +string Action; +int MenuButton=0; double lastangle; @@ -133,29 +135,23 @@ pthread_t mainthread; pthread_cond_t initSignal=PTHREAD_COND_INITIALIZER; pthread_mutex_t initLock=PTHREAD_MUTEX_INITIALIZER; -pthread_cond_t quitSignal=PTHREAD_COND_INITIALIZER; -pthread_mutex_t quitLock=PTHREAD_MUTEX_INITIALIZER; - pthread_cond_t readySignal=PTHREAD_COND_INITIALIZER; pthread_mutex_t readyLock=PTHREAD_MUTEX_INITIALIZER; -#endif -inline void lock() +void endwait(pthread_cond_t& signal, pthread_mutex_t& lock) { -#ifdef HAVE_LIBPTHREAD - if(glthread) - pthread_mutex_lock(&readyLock); -#endif + pthread_mutex_lock(&lock); + pthread_cond_signal(&signal); + pthread_mutex_unlock(&lock); } - -inline void unlock() +void wait(pthread_cond_t& signal, pthread_mutex_t& lock) { -#ifdef HAVE_LIBPTHREAD - if(glthread) - pthread_mutex_unlock(&readyLock); -#endif - + pthread_mutex_lock(&lock); + pthread_cond_signal(&signal); + pthread_cond_wait(&signal,&lock); + pthread_mutex_unlock(&lock); } +#endif template<class T> inline T min(T a, T b) @@ -296,6 +292,14 @@ void update() void drawscene(double Width, double Height) { +#ifdef HAVE_LIBPTHREAD + static bool first=true; + if(glthread && first) { + wait(initSignal,initLock); + endwait(initSignal,initLock); + first=false; + } +#endif glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if(!ViewportLighting) @@ -362,7 +366,7 @@ void Export() ++count; } while (trEndTile(tr)); if(settings::verbose > 1) - cout << count << " tile" << (count > 1 ? "s" : "") << " drawn" << endl; + cout << count << " tile" << (count != 1 ? "s" : "") << " drawn" << endl; trDelete(tr); picture pic; @@ -384,17 +388,13 @@ void Export() outOfMemory(); } setProjection(); -} -void LockedExport() -{ - if(interact::interactive) - lock(); - Export(); - if(interact::interactive) - unlock(); +#ifdef HAVE_LIBPTHREAD + if(glthread) + endwait(readySignal,readyLock); +#endif } - + void windowposition(int& x, int& y, int width=Width, int height=Height) { pair z=getSetting<pair>("position"); @@ -486,13 +486,13 @@ void updateHandler(int) { initlighting(); update(); - if(interact::interactive) { - glutShowWindow(); - glutShowWindow(); // Call twice to work around apparent freeglut bug. - } else if(glthread) fitscreen(); + glutShowWindow(); + glutShowWindow(); // Call twice to work around apparent freeglut bug. + if(glthread && !interact::interactive) + fitscreen(); } -void autoExport() +void exportHandler(int) { if(!Iconify) glutShowWindow(); @@ -501,16 +501,6 @@ void autoExport() glutHideWindow(); } -void exportHandler(int) -{ -#ifdef HAVE_LIBPTHREAD - if(glthread) - wait(readySignal,readyLock); -#endif - initlighting(); - autoExport(); -} - void reshape(int width, int height) { if(glthread) { @@ -519,7 +509,6 @@ void reshape(int width, int height) initialize=false; signal(SIGUSR1,updateHandler); signal(SIGUSR2,exportHandler); - unlock(); } } @@ -529,38 +518,14 @@ void reshape(int width, int height) reshape0(width,height); } -#ifdef HAVE_LIBPTHREAD -void endwait(pthread_cond_t& signal, pthread_mutex_t& lock) -{ - pthread_cond_signal(&signal); -} -void wait(pthread_cond_t& signal, pthread_mutex_t& lock) -{ - pthread_mutex_lock(&lock); - pthread_cond_signal(&signal); - pthread_cond_wait(&signal,&lock); - endwait(signal,lock); - pthread_mutex_unlock(&lock); -} - -#endif - void quit() { if(glthread) { - if(interact::interactive) { - glutHideWindow(); - } else { - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glutSwapBuffers(); - } + glutHideWindow(); #ifdef HAVE_LIBPTHREAD - if(!interact::interactive) { - pthread_mutex_lock(&quitLock); - pthread_cond_signal(&quitSignal); - pthread_mutex_unlock(&quitLock); - } -#endif + if(!interact::interactive) + endwait(readySignal,readyLock); +#endif } else { glutDestroyWindow(window); exit(0); @@ -569,16 +534,12 @@ void quit() void display() { - if(interact::interactive) - lock(); drawscene(Width,Height); glutSwapBuffers(); if(queueExport) { Export(); queueExport=false; } - if(interact::interactive) - unlock(); if(!glthread) { if(Oldpid != 0 && waitpid(Oldpid,NULL,WNOHANG) != Oldpid) { kill(Oldpid,SIGHUP); @@ -608,7 +569,8 @@ void capzoom() void disableMenu() { - glutDetachMenu(GLUT_RIGHT_BUTTON); + if(MenuButton) + glutDetachMenu(MenuButton); Menu=false; } @@ -658,8 +620,8 @@ void rotate(int x, int y) } Motion=true; arcball.mouse_motion(x,Height-y,0, - mod == GLUT_ACTIVE_SHIFT, // X rotation only - mod == GLUT_ACTIVE_CTRL); // Y rotation only + Action == "rotateX", // X rotation only + Action == "rotateY"); // Y rotation only for(int i=0; i < 4; ++i) { const vec4& roti=arcball.rot[i]; @@ -738,31 +700,81 @@ void rotateZ(int x, int y) #define GLUT_WHEEL_DOWN 4 #endif -// Mouse bindings. -// LEFT: rotate -// SHIFT LEFT: zoom -// CTRL LEFT: shift -// MIDDLE: menu -// RIGHT: zoom -// SHIFT RIGHT: rotateX -// CTRL RIGHT: rotateY -// ALT RIGHT: rotateZ +string action(int button, int mod) +{ + size_t Button; + size_t nButtons=5; + switch(button) { + case GLUT_LEFT_BUTTON: + Button=0; + break; + case GLUT_MIDDLE_BUTTON: + Button=1; + break; + case GLUT_RIGHT_BUTTON: + Button=2; + break; + case GLUT_WHEEL_UP: + Button=3; + break; + case GLUT_WHEEL_DOWN: + Button=4; + break; + default: + Button=nButtons; + } + + size_t Mod; + size_t nMods=4; + switch(mod) { + case 0: + Mod=0; + break; + case GLUT_ACTIVE_SHIFT: + Mod=1; + break; + case GLUT_ACTIVE_CTRL: + Mod=2; + break; + case GLUT_ACTIVE_ALT: + Mod=3; + break; + default: + Mod=nMods; + } + + if(Button >= 0 && Button < nButtons) { + array *left=getSetting<array *>("leftbutton"); + array *middle=getSetting<array *>("middlebutton"); + array *right=getSetting<array *>("rightbutton"); + array *wheelup=getSetting<array *>("wheelup"); + array *wheeldown=getSetting<array *>("wheeldown"); + array *Buttons[]={left,middle,right,wheelup,wheeldown}; + array *a=Buttons[button]; + size_t size=checkArray(a); + if(Mod >= 0 && Mod < (Int) size) + return read<string>(a,Mod); + } + return ""; +} + void mouse(int button, int state, int x, int y) { - if(button == GLUT_WHEEL_UP) { + string Action=action(button,glutGetModifiers()); + + if(Action == "zoomin") { mousewheel(0,1,x,y); return; } - if(button == GLUT_WHEEL_DOWN) { + if(Action == "zoomout") { mousewheel(0,-1,x,y); return; } - mod=glutGetModifiers(); - - if(button == GLUT_RIGHT_BUTTON) { + if(Action == "zoom/menu") { if(state == GLUT_UP && !Motion) { - glutAttachMenu(GLUT_RIGHT_BUTTON); + MenuButton=button; + glutAttachMenu(button); Menu=true; return; } @@ -772,24 +784,19 @@ void mouse(int button, int state, int x, int y) else Motion=false; if(state == GLUT_DOWN) { - if(button == GLUT_LEFT_BUTTON && mod == GLUT_ACTIVE_CTRL) { + if(Action == "rotate" || Action == "rotateX" || Action == "rotateY") { + arcball.mouse_down(x,Height-y); + glutMotionFunc(rotate); + } else if(Action == "shift") { x0=x; y0=y; glutMotionFunc(move); - return; - } - if((button == GLUT_LEFT_BUTTON && mod == GLUT_ACTIVE_SHIFT) || - (button == GLUT_RIGHT_BUTTON && mod == 0)) { + } else if(Action == "zoom" || Action == "zoom/menu") { y0=y; glutMotionFunc(zoom); - return; - } - if(button == GLUT_RIGHT_BUTTON && mod == GLUT_ACTIVE_ALT) { + } else if(Action == "rotateZ") { lastangle=Degrees(x,y); glutMotionFunc(rotateZ); - return; } - arcball.mouse_down(x,Height-y); - glutMotionFunc(rotate); } else arcball.mouse_up(); } @@ -856,12 +863,12 @@ void mode() case 1: for(size_t i=0; i < Nlights; ++i) glDisable(GL_LIGHT0+i); - gluNurbsProperty(nurb,GLU_DISPLAY_MODE,GLU_OUTLINE_POLYGON); glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + gluNurbsProperty(nurb,GLU_DISPLAY_MODE,GLU_OUTLINE_PATCH); ++Mode; break; case 2: - gluNurbsProperty(nurb,GLU_DISPLAY_MODE,GLU_OUTLINE_PATCH); + gluNurbsProperty(nurb,GLU_DISPLAY_MODE,GLU_OUTLINE_POLYGON); Mode=0; break; } @@ -974,7 +981,7 @@ void keyboard(unsigned char key, int x, int y) mode(); break; case 'e': - LockedExport(); + Export(); break; case 'c': camera(); @@ -989,7 +996,7 @@ void keyboard(unsigned char key, int x, int y) break; case 17: // Ctrl-q case 'q': - if(!Format.empty()) LockedExport(); + if(!Format.empty()) Export(); quit(); break; } @@ -1077,8 +1084,6 @@ void glrender(const string& prefix, const picture *pic, const string& format, static bool initializedView=false; - if(view || initializedView) lock(); - Prefix=prefix; Picture=pic; Format=format; @@ -1093,13 +1098,6 @@ void glrender(const string& prefix, const picture *pic, const string& format, View=view; Oldpid=oldpid; - static bool initialized=false; - - if(!initialized) { - init(); - Fitscreen=1; - } - Xmin=m.getx(); Xmax=M.getx(); Ymin=m.gety(); @@ -1113,6 +1111,15 @@ void glrender(const string& prefix, const picture *pic, const string& format, ignorezoom=false; Mode=0; + static bool initialize=true; + + if(initialize) { + initialize=false; + init(); + Fitscreen=1; + } + + static bool initialized=false; if(!initialized || !interact::interactive) { antialias=getSetting<Int>("antialias") > 1; double expand=getSetting<double>("render"); @@ -1163,12 +1170,9 @@ void glrender(const string& prefix, const picture *pic, const string& format, } #ifdef HAVE_LIBPTHREAD - if(initializedView && glthread) { - if(View) - pthread_kill(mainthread,SIGUSR1); - else - pthread_kill(mainthread,SIGUSR2); - unlock(); + if(glthread && initializedView) { + if(!View) queueExport=true; + pthread_kill(mainthread,SIGUSR1); return; } #endif @@ -1177,6 +1181,10 @@ void glrender(const string& prefix, const picture *pic, const string& format, bool havewindow=initialized && glthread; + int buttons[]={GLUT_LEFT_BUTTON,GLUT_MIDDLE_BUTTON,GLUT_RIGHT_BUTTON}; + string buttonnames[]={"left","middle","right"}; + size_t nbuttons=sizeof(buttons)/sizeof(int); + if(View) { int x,y; if(havewindow) @@ -1200,8 +1208,13 @@ void glrender(const string& prefix, const picture *pic, const string& format, glutSetOption(GLUT_MULTISAMPLE,multisample); #endif #endif - string title=string(settings::PROGRAM)+": "+prefix+ - " [Double click right button for menu]"; + string title=string(settings::PROGRAM)+": "+prefix; + for(size_t i=0; i < nbuttons; ++i) { + int button=buttons[i]; + if(action(button,0) == "zoom/menu") + title += " [Double click "+buttonnames[i]+" button for menu]"; + } + window=glutCreateWindow(title.c_str()); GLint samplebuf[1]; glGetIntegerv(GL_SAMPLES,samplebuf); @@ -1269,7 +1282,6 @@ void glrender(const string& prefix, const picture *pic, const string& format, mode(); initlighting(); - if(View) { initializedView=true; glutReshapeFunc(reshape); @@ -1289,16 +1301,16 @@ void glrender(const string& prefix, const picture *pic, const string& format, glutAddMenuEntry("(c) Camera",CAMERA); glutAddMenuEntry("(q) Quit" ,QUIT); - glutAttachMenu(GLUT_MIDDLE_BUTTON); - + for(size_t i=0; i < nbuttons; ++i) { + int button=buttons[i]; + if(action(button,0) == "menu") + glutAttachMenu(button); + } + glutMainLoop(); } else { - if(glthread) { - exportHandler(0); - } else { - autoExport(); - quit(); - } + exportHandler(0); + if(!glthread) quit(); } } |