From 0199cab552ef0687112ce56c69ac76d99adbc6bc Mon Sep 17 00:00:00 2001 From: Gilles Marckmann <gilles.marckmann@ec-nantes.fr> Date: Fri, 22 Oct 2010 11:10:37 +0000 Subject: [PATCH] mainGlut has been modified to use camera viewing (with command gluLookAt() ) and tou be able to turn on stereo device --- utils/api_demos/mainGlut.cpp | 447 +++++++++++++++++++++++++++++++---- 1 file changed, 405 insertions(+), 42 deletions(-) diff --git a/utils/api_demos/mainGlut.cpp b/utils/api_demos/mainGlut.cpp index 67cb5f177d..a0c1276e10 100644 --- a/utils/api_demos/mainGlut.cpp +++ b/utils/api_demos/mainGlut.cpp @@ -1,3 +1,4 @@ + // // A simple example on how to build a GUI frontend to Gmsh using GLUT // @@ -5,118 +6,480 @@ #if defined(__APPLE__) # include <GLUT/glut.h> #else +# include <GL/gl.h> # include <GL/glut.h> +# include <GL/glu.h> #endif #include "Gmsh.h" +#include <stdio.h> +#include "string.h" #include "GModel.h" #include "MElement.h" +#include "Context.h" #include "drawContext.h" +#include "Trackball.h" +#include "Camera.h" + + +typedef struct { + double r,g,b; +} COLOUR; +typedef struct { + unsigned char r,g,b,a; +} PIXELA; +using namespace std; drawContext *ctx = 0; +Camera camera; +mouseAndKeyboard mouseandkeys; + + +static int xprev = 0, yprev = 0, specialkey = 0; class drawContextGlut : public drawContextGlobal{ - public: +public: void draw(){ ctx->draw3d(); ctx->draw2d(); } const char *getFontName(int index){ return "Helvetica"; } - int getFontSize(){ return 18; } + int getFontSize(){ return 12; } double getStringWidth(const char *str) { - return glutBitmapLength(GLUT_BITMAP_HELVETICA_18, (const unsigned char*)str); + return glutBitmapLength(GLUT_BITMAP_HELVETICA_12, (const unsigned char*)str); } - int getStringHeight(){ return 18; } + int getStringHeight(){ return 12; } int getStringDescent(){ return 6; } void drawString(const char *str) { for (int i = 0; i < strlen(str); i++) glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, str[i]); } + }; + + + + + + + + // GLUT callbacks + void display() { - glViewport(ctx->viewport[0], ctx->viewport[1], - ctx->viewport[2], ctx->viewport[3]); - glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); - drawContext::global()->draw(); - glutSwapBuffers(); + + if (!camera.stereoEnable) { + // cout<<" display();"<<endl; + glViewport(ctx->viewport[0], ctx->viewport[1], + ctx->viewport[2], ctx->viewport[3]); + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + double dist,ratio,radians,scale,wd2,ndfl,left,right,top,bottom ; + double near=0.1 ; double far=10000; + double h= 1.*( ctx->viewport[3]-ctx->viewport[1]); + double w= 1.*( ctx->viewport[2]-ctx->viewport[0]) ; + ratio =w/h ; + radians = 0.0174532925 * camera.aperture / 2; + wd2 = near * tan(radians); + ndfl = near / camera.focallength; + ndfl=1; + + // fill the background + // ctx->initProjection(); + // defines the lights + // ctx->initRenderModel(); + // defines screen plane and frame + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + left = - ratio * wd2; + right = ratio * wd2; + top = wd2; + bottom = - wd2; + glFrustum(left,right,bottom,top,near,far); + glMatrixMode(GL_MODELVIEW); + glDrawBuffer(GL_BACK); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glLoadIdentity(); + gluLookAt(camera.position.x, + camera.position.y, + camera.position.z, + camera.target.x, + camera.target.y, + camera.target.z, + camera.up.x, + camera.up.y, + camera.up.z); + drawContext::global()->draw(); + glutSwapBuffers(); + } + else { + // cout<<" display3D();"<<endl; + glViewport(ctx->viewport[0], ctx->viewport[1], + ctx->viewport[2], ctx->viewport[3]); + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + double dist,ratio,radians,scale,wd2,ndfl,left,right,top,bottom ; + double near=0.1 ; double far=10000; + double h= 1.*( ctx->viewport[3]-ctx->viewport[1]); + double w= 1.*( ctx->viewport[2]-ctx->viewport[0]) ; + // 4:3 , 16:9, ... + ratio =w/h ; + // demi angle de vue (en radian) + radians = 0.0174532925 * camera.aperture / 2; + + wd2 = near * tan(radians); + ndfl = near / camera.focallength; + + XYZ eye; + // fill the background + // ctx->initProjection(); + // defines the lights + // ctx->initRenderModel(); + //right eye + eye.x = camera.right.x*camera.eyesep / 2.0; + eye.y = camera.right.y*camera.eyesep / 2.0; + eye.z = camera.right.z*camera.eyesep / 2.0; + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + left = - ratio * wd2 - 0.5 * camera.eyesep * ndfl; + right = ratio * wd2 - 0.5 * camera.eyesep * ndfl; + top = wd2; + bottom = - wd2; + glFrustum(left,right,bottom,top,near,far); + glMatrixMode(GL_MODELVIEW); + glDrawBuffer(GL_BACK_RIGHT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glLoadIdentity(); + gluLookAt(camera.position.x+eye.x, + camera.position.y+eye.y, + camera.position.z+eye.z, + camera.target.x+eye.x, + camera.target.y+eye.y, + camera.target.z+eye.z, + camera.up.x, + camera.up.y, + camera.up.z); + drawContext::global()->draw(); + + //left eye + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + left = - ratio * wd2 + 0.5 * camera.eyesep * ndfl; + right = ratio * wd2 + 0.5 * camera.eyesep * ndfl; + top = wd2; + bottom = - wd2; + glFrustum(left,right,bottom,top,near,far); + + glMatrixMode(GL_MODELVIEW); + glDrawBuffer(GL_BACK_LEFT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glLoadIdentity(); + gluLookAt(camera.position.x-eye.x, + camera.position.y-eye.y, + camera.position.z-eye.z, + camera.target.x-eye.x, + camera.target.y-eye.y, + camera.target.z-eye.z, + camera.up.x, + camera.up.y, + camera.up.z); + drawContext::global()->draw(); + + glutSwapBuffers(); + } + } + + + + + void reshape(int w, int h) { ctx->viewport[2] = w; ctx->viewport[3] = h; - display(); + display(); } + + + void keyboard(unsigned char key, int x, int y) { - switch(key){ - case '1': GModel::current()->mesh(1); break; - case '2': GModel::current()->mesh(2); break; - case '3': GModel::current()->mesh(3); break; - } display(); } -static int xprev = 0, yprev = 0, specialkey = 0; + + void motion(int x, int y) { - int w = ctx->viewport[2]; - int h = ctx->viewport[3]; - if(specialkey == GLUT_ACTIVE_SHIFT){ - double dx = x - xprev; - double dy = y - yprev; - if(fabs(dy) > fabs(dx)) { - double fact = (4. * fabs(dy) + h) / (double)h; - ctx->s[0] *= ((dy > 0) ? fact : 1. / fact); - ctx->s[1] = ctx->s[0]; - ctx->s[2] = ctx->s[0]; - } + int w = (ctx->viewport[2] - ctx->viewport[0]); + int h = (ctx->viewport[3] - ctx->viewport[1]); + //rotate + if (mouseandkeys.button_left_down && (mouseandkeys.mode!= GLUT_ACTIVE_CTRL) ){ + double x_r = 2.*(1.*x - w/2.)/w; + double y_r = 2.*(1.*y - h/2.)/h; + double xprev_r=2.*(1.*xprev - w/2.)/w; + double yprev_r=2.*(1.*yprev - h/2.)/h; + double q[4]; + trackball(q,xprev_r,yprev_r,x_r,y_r); + camera.rotate(q); + xprev = x; + yprev = y; } - else{ - ctx->addQuaternion((2. * xprev - w) / w, (h - 2. * yprev) / h, - (2. * x - w) / w, (h - 2. * y) / h); + //zoom + if (mouseandkeys.button_middle_down ){ + double dy= y-yprev; + double factor =( CTX::instance()->zoomFactor * fabs(dy) +(double) h) / (double)h; + factor = ((dy > 0) ? factor : 1./factor); + // cout<<" zoom factor: "<<factor<<endl; + camera.distance=fabs(1./factor*camera.ref_distance); + camera.position.x=camera.target.x-camera.distance*camera.view.x; + camera.position.y=camera.target.y-camera.distance*camera.view.y; + camera.position.z=camera.target.z-camera.distance*camera.view.z; + } + // translate + if (mouseandkeys.button_right_down ){ + // cout<<" prev: "<<xprev<<" "<<yprev<<"-> x,y: "<<x<<" "<<y<<endl; + double x_r = 2.*(1.*x - w/2.)/w; + double y_r = 2.*(1.*y - h/2.)/h; + double xprev_r=2.*(1.*xprev - w/2.)/w; + double yprev_r=2.*(1.*yprev - h/2.)/h; + + double theta_x=camera.aperture*(x_r-xprev_r)*0.0174532925/2. ; + double theta_y=camera.aperture*(y_r-yprev_r)*0.0174532925/2. ; + // cout<<" theta_x : "<<theta_x<<endl; + // cout<<" theta_y : "<<theta_y<<endl; + + camera.moveRight(theta_x); + camera.moveUp(theta_y); + xprev = x; + yprev = y; + } + if (!mouseandkeys.button_middle_down ){ + xprev = x; + yprev = y; } - xprev = x; - yprev = y; display(); } + + + + void mouse(int button, int state, int x, int y) { specialkey = glutGetModifiers(); + xprev = x; yprev = y; + if (button == GLUT_LEFT_BUTTON) { + mouseandkeys.button_left_down=!state; + } + else if (button == GLUT_MIDDLE_BUTTON) { + mouseandkeys.button_middle_down=!state; + } + else { + mouseandkeys.button_right_down=!state; + } + camera.ref_distance=camera.distance; +} + + + + + +void processSpecialKeys(int key, int x, int y) { + + mouseandkeys.mode = glutGetModifiers(); + if (mouseandkeys.mode == GLUT_ACTIVE_CTRL) { + // cout<<"CTRL "<<key<<endl; + switch(key){ + case 100 : /* 'left' */ + // camera.closeness*=.99; + display(); + camera.focallength=camera.focallength*.99; + camera.eyesep=(camera.focallength/camera.distance)*camera.distance*camera.ratio; + break; + case 102 : /* 'right' */ + //camera.closeness*=1.01; + camera.focallength=camera.focallength*1.01; + camera.eyesep=(camera.focallength/camera.distance)*camera.distance*camera.ratio; + display(); + break; + } + } + else{ + switch(key){ + mouseandkeys.key= key ; + // cout<<"special key "<<key<<endl; + // cout<<"move in special key :"<<x<<" "<<y<<endl; + case 101 : /* 'up' */ + camera.focallength*=1.1; + // display(); + break; + case 103 : /* 'down' */ + camera.focallength*=0.9; + // display(); + break; + case 100 : /* 'left' */ + camera.eyesep*=.9; + // display(); + break; + case 102 : /* 'right' */ + camera.eyesep*=1.1; + // display(); + break; + } + } + // camera.ratio=camera.eyesep/camera.focallength; + // camera.closeness= camera.distance/camera.focallength; + camera.update(); + display(); + + cout<<"eyesep = "<< camera.eyesep<<" / focallength = "<< camera.focallength<<" / ratio = "; + cout<< camera.ratio<<" / distance = "<< camera.distance<<" / closeness = "<< camera.closeness<<endl; + mouseandkeys.mode = 0; +} + + + + +void processNormalKeys(unsigned char key, int x, int y) { + double def; + + if (key != 0) { + // cout<<"normal key "<<key; + mouseandkeys.key= key ; + // cout<<" = "<<mouseandkeys.key<<endl; + // cout<<"move in normal key :"<<x<<" "<<y<<endl; + mouseandkeys.mode = glutGetModifiers(); + // if (mouseandkeys.mode == GLUT_ACTIVE_CTRL) cout<<"CTRL "<<key<<endl; + if (mouseandkeys.mode == GLUT_ACTIVE_CTRL && key==17) exit(0); + + } + switch(key){ + case 49: GModel::current()->mesh(1); break; /* '1' */ + case 50: GModel::current()->mesh(2); break; /* '2' */ + case 51: GModel::current()->mesh(3); break; /* '3' */ + case 48 : /* '0' */ + camera.lookAtCg(); + display(); + break; + case 114 : /* 'R' */ + camera.init(); + display(); + break; + case 'f' : /* 'F' */ + camera.screenwidth=ctx->viewport[2]; + camera.screenheight=ctx->viewport[3]; + glutFullScreen(); + display(); + break; + case 27 : /* 'ech' */ + glutReshapeWindow(camera.screenwidth ,camera.screenheight ); + //glutReshapeWindow(500,500 ); + display(); + break; + case 100 : ; /* 'D' */ + GmshSetOption("View","VectorType",5.); + display(); + break; + case 43 : /* '+' */ + GmshGetOption("View", "DisplacementFactor", def); + def*=2.; + GmshSetOption("View","DisplacementFactor",def); + display(); + break; + case 45 : ; /* '-' */ + GmshGetOption("View", "DisplacementFactor", def); + def*=.5; + GmshSetOption("View","DisplacementFactor",def); + display(); + break; + case 112 : /* 'p' */ + // cout<<"*--*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*--*-*-*-*-*-*-*-*-*-*-***-*---*-***-"<<endl; + break; + } + } + + + +//******************************************************* +//******************************************************* +//******************************************************* + int main(int argc, char **argv) { + GmshInitialize(argc, argv); GmshSetOption("General", "Terminal", 1.); - GmshSetOption("View", "IntervalsType", 1.); - GmshSetOption("View", "AdaptVisualizationGrid", 1.); - GmshSetOption("View", "TargetError", 0.00001); - GmshSetOption("View", "MaxRecursionLevel", 3.); + GmshSetOption("General", "Stereo", 0.); + GmshSetOption("General", "Camera", 1.); + GmshSetOption("General", "Orthographic", 0.); + + if (strstr(argv[1],"-s") != NULL){ + camera.stereoEnable = true; + cout<<"mode STEREO"<<endl; + GmshSetOption("General", "Stereo", 1.); + } for(int i = 1; i < argc; i++) GmshMergeFile(argv[i]); - ctx = new drawContext(); drawContext::setGlobal(new drawContextGlut); - + glutInit(&argc, argv); - glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); - glutInitWindowSize(ctx->viewport[2], ctx->viewport[3]); - glutInitWindowPosition(100, 100); - glutCreateWindow("GLUT Gmsh Viewer"); + if (camera.stereoEnable) { + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_STEREO); + // GmshSetOption("General", "BackgroundGradient", 0.); + } + else { + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ); + } glutDisplayFunc(display); + glutInitWindowSize(ctx->viewport[2], ctx->viewport[3]); + glutInitWindowPosition(400,10); + glutInitWindowSize(800,800); + glutCreateWindow("GLUT Gmsh Viewer"); + + camera.lookAtCg(); + glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMotionFunc(motion); glutMouseFunc(mouse); + glutKeyboardFunc(processNormalKeys); + glutSpecialFunc(processSpecialKeys); + + + cout<<"-------------------------------------"<<endl; + cout<<" SHORTCUTS "<<endl; + cout<<"-------------------------------------"<<endl; + cout<<" Ctrl+Q Quit "<<endl; + cout<<" 1 mesh line "<<endl; + cout<<" 2 mesh surface "<<endl; + cout<<" 3 mesh volume "<<endl; + cout<<" R resize "<<endl; + cout<<" 0 origine "<<endl; + cout<<" option -s stereo on "<<endl; + cout<<" F full screen on "<<endl; + cout<<" ech full screen off"<<endl; + cout<<" D displacement field"<<endl; + cout<<" + deformed +"<<endl; + cout<<" - deformed -"<<endl; + cout<<" up focal length +"<<endl; + cout<<" down focal length -"<<endl; + cout<<" left eye sep -"<<endl; + cout<<" right eye sep +"<<endl; + cout<<"-------------------------------------"<<endl; + glutMainLoop(); GmshFinalize(); return 0; } + + + -- GitLab