scene.c
来自「FreeFem++可以生成高质量的有限元网格。可以用于流体力学」· C语言 代码 · 共 931 行 · 第 1/2 页
C
931 行
glDisable(GL_LIGHTING); /* draw clipping plane */ if ( clip->active & C_ON ) { drawClip(sc,clip,mesh,0); glClipPlane(GL_CLIP_PLANE0,clip->eqn); glEnable(GL_CLIP_PLANE0); } else glDisable(GL_CLIP_PLANE0); /* draw object if static scene */ sstatic = view->mstate > 0 && clip->cliptr->mstate > 0; if ( sstatic || sc->type & S_FOLLOW ) { displayScene(sc,sc->mode,0); if ( sc->item & S_NUMP || sc->item & S_NUMF ) listNum(sc,mesh); /* draw normals */ if ( sc->type & S_NORMAL ) { if ( !sc->nlist ) sc->nlist = drawNormals(mesh,sc); glCallList(sc->nlist); } /* draw data */ if ( sstatic ) displayData(sc,mesh); } else if ( !(sc->item & S_BOX) ) drawBox(sc,mesh,0); /* draw ridges, corners, etc. */ if ( (sc->item & S_GEOM) && sc->glist ) { glDisable(GL_LIGHTING); if ( !mesh->ne ) glPointSize(1); else glPointSize(5); glDisable(GL_COLOR_MATERIAL); glCallList(sc->glist); } glDisable(GL_CLIP_PLANE0); if ( clip->active & C_EDIT || sc->item & S_BOX ) drawBox(sc,mesh,0); if ( sc->item & S_AXIS ) drawAxis(sc,mesh->dim); if ( (mesh->dim == 3 || sc->mode & S_ALTITUDE) && sc->item & S_GRID ) drawBase(sc,mesh); if ( sc->cube->active & C_ON ) drawCube(sc,mesh); sstatic |= tiling; if ( sstatic && clip->active & C_ON && clip->active & C_VOL ) displayScene(sc,sc->mode,1); if ( sc->picklist && !(sc->isotyp & S_PARTICLE) ) { glEnable(GL_LIGHTING); glEnable(GL_COLOR_MATERIAL); glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); glDisable(GL_POLYGON_OFFSET_FILL); glCallList(sc->picklist); glEnable(GL_POLYGON_OFFSET_FILL); glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); glDisable(GL_COLOR_MATERIAL); glDisable(GL_LIGHTING); } /* show path, if any */ if ( sc->type & S_PATH && sc->path.tlist ) glCallList(sc->path.tlist);}void redrawMorphing(pScene sc) { pMesh mesh; if ( morphing ) { mesh = cv.mesh[sc->idmesh]; if ( !morphMesh(sc,mesh) ) return; }}/* animate */void glutIdle(void) { static float timePassed = 0.0; static float timeRedraw = 0.02; /*1.0 / 50.0*/ float clk,timeElaps; clk = clock(); timeElaps = (clk - timePassed) / (float)CLOCKS_PER_SEC; if ( timeElaps >= timeRedraw ) { timePassed = clk; glutPostRedisplay(); }}void streamIdle(void) { pScene sc; pMesh mesh; float elp; clock_t tim; static clock_t timbase= 0; static float maxtim = 0.; sc = cv.scene[currentScene()]; sc->par.cumtim += sc->par.dt; sc->par.advtim = 1; if ( sc->par.cumtim > sc->par.maxtime ) { sc->par.cumtim = 0.0; sc->par.cumpertime = 0.0; saveimg = 0; sc->isotyp &= ~S_PARTICLE; glutIdleFunc(0); printf("\nfin"); } else if ( sc->par.cumpertime >= sc->par.pertime ) { mesh = cv.mesh[sc->idmesh]; sc->par.cumpertime = 0.0; if ( !animParticle(sc,mesh) ) { sc->par.cumtim = 0.0; sc->par.cumpertime = 0.0; saveimg = 0; glutIdleFunc(0); printf("\nfin"); } else glutPostRedisplay(); } else glutPostRedisplay(); return; if ( timbase < 1 ) { timbase = clock(); maxtim = 0.0; sc->par.advtim = 0; glutPostRedisplay(); } else { tim = clock(); elp = (tim - timbase) / (float)CLOCKS_PER_SEC; if ( elp > sc->par.dt ) { timbase = tim; maxtim += elp; sc->par.advtim = 1; if ( maxtim > sc->par.maxtime ) glutIdleFunc(0); } sc->par.cumtim += sc->par.dt; glutPostRedisplay(); }}/* OpenGL callbacks */void redrawScene() { pScene sc,slave; pTransform view; pPersp p; pCamera c; double ndfl,ratio,top,bottom,left,right,nnear,ffar; sc = cv.scene[currentScene()]; view = sc->view; p = sc->persp; c = sc->camera; if ( stereoMode == MONO || !hasStereo ) { glDrawBuffer(GL_BACK_LEFT); glClearColor(sc->par.back[0],sc->par.back[1], sc->par.back[2],sc->par.back[3]); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0.,0.,-p->depth, 0.,0.,0., 0.0,1.0,0.0); setupView(sc); glMultMatrixf(view->matrix); glTranslatef(sc->cx,sc->cy,sc->cz); drawModel(sc); if ( sc->type & S_DECO ) redrawStatusBar(sc); } else { nnear = -p->depth - 0.5 * sc->dmax; if ( nnear < 0.1 ) nnear = 0.1; ffar = -p->depth + 0.5 * sc->dmax; ratio = sc->par.xs / (double)sc->par.ys; top = nnear * tan(DTOR * 0.5 * p->fovy); ndfl = nnear / p->depth; if ( sc->par.eyesep < 0.0 ) sc->par.eyesep = fabs(p->depth / 20.0); /* left view */ glDrawBuffer(GL_BACK_LEFT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); left = -ratio * top + 0.5 * sc->par.eyesep * ndfl; right = ratio * top + 0.5 * sc->par.eyesep * ndfl; bottom= -top; glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(left,right,top,bottom,nnear,ffar); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(-sc->par.eyesep,0.,-p->depth, sc->par.eyesep/3.0,0.,0., 0.0,1.0,0.0); setupView(sc); glMultMatrixf(view->matrix); glTranslatef(sc->cx,sc->cy,sc->cz); drawModel(sc); if ( sc->type & S_DECO ) redrawStatusBar(sc); /* right view */ glDrawBuffer(GL_BACK_RIGHT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); left = -ratio * top - 0.5 * sc->par.eyesep * ndfl; right = ratio * top - 0.5 * sc->par.eyesep * ndfl; glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(left,right,top,bottom,nnear,ffar); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(sc->par.eyesep,0.,-p->depth, sc->par.eyesep/3.0,0.,0., 0.0,1.0,0.0); setupView(sc); glMultMatrixf(view->matrix); glTranslatef(sc->cx,sc->cy,sc->cz); drawModel(sc); if ( sc->type & S_DECO ) redrawStatusBar(sc); } /* refresh screen */ if ( saveimg && animate ) glFlush(); else glutSwapBuffers(); if ( ddebug ) checkErrors(); if ( saveimg && !(sc->type & S_SCISSOR) ) keyFile('H',0,0); /* redraw linked scene */ if ( !animate && sc->slave > -1 ) { slave = cv.scene[sc->slave]; glutSetWindow(slave->idwin); redrawScene(); }}/* OpenGL callbacks */void redrawSchnauzer() { pScene sc = cv.scene[currentScene()]; pMesh mesh; char *ptr,data[256]; mesh = cv.mesh[sc->idmesh]; strcpy(data,mesh->name); ptr = (char*)strstr(data,".mesh"); if ( ptr ) *ptr = '\0'; ptr = (char*)strstr(data,".gis"); if ( ptr ) *ptr = '\0'; strcat(data,".ppm"); redrawScene(); imgHard(sc,data,'H'); exit(0);}void deleteScene(pScene sc) { /* default */ if ( ddebug) printf("deleteScene\n"); M_free(sc->view); M_free(sc->clip); M_free(sc->persp); M_free(sc->camera); M_free(sc->material); M_free(sc->matsort); M_free(sc);}void initGrafix(pScene sc,pMesh mesh) { GLfloat lightamb[4] = { 0.3, 0.3, 0.3, 1.0 }; GLfloat lightdif[4] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat lightpos[4] = { 0.0, 0.0, 1.0, 0.0 }; if ( ddebug ) printf("initGrafix\n"); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glPolygonOffset(1.0, 1.0 / (float)0x10000); glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); glShadeModel(GL_SMOOTH); glDisable(GL_NORMALIZE); glDisable(GL_LINE_SMOOTH); glDisable(GL_POINT_SMOOTH); glDisable(GL_DITHER); glDisable(GL_CULL_FACE); if ( mesh->typ == 2 ) { glEnable(GL_CULL_FACE); glCullFace(GL_BACK); } glPixelStorei(GL_UNPACK_ALIGNMENT,1); /* lighting */ glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE); glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER,GL_FALSE);#if ( !defined(GL_VERSION_1_1) ) glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);#endif glLightfv(GL_LIGHT0,GL_DIFFUSE,lightdif); glLightfv(GL_LIGHT0,GL_AMBIENT,lightamb); glEnable(GL_LIGHTING); if ( stereoMode != MONO ) { lightpos[2] = -1.0; if ( sc->par.sunpos ) sc->par.sunpos[2] = -fabs(sc->par.sunpos[2]); } if ( sc->par.sunp ) glLightfv(GL_LIGHT0,GL_POSITION,sc->par.sunpos); else glLightfv(GL_LIGHT0,GL_POSITION,lightpos); glEnable(GL_LIGHT0);}/* new scene */int createScene(pScene sc,int idmesh) { pMesh mesh; char data[128]; /* default */ mesh = cv.mesh[idmesh]; if ( !quiet ) fprintf(stdout," Computing 3D scene\n"); /* set default mode */ sc->idmesh = idmesh; sc->par.xi = sc->par.yi = 10; if ( option == SCHNAUZER ) { sc->par.xs = schw; sc->par.ys = schh; } else { if ( sc->par.xs == 0 ) sc->par.xs = 600; if ( sc->par.ys == 0 ) sc->par.ys = 600; } if ( !sc->mode ) sc->mode = HIDDEN; sc->item = 0; sc->shrink = 1.0; sc->slave = sc->master = -1; sc->picked = 0; if ( mesh->nvn == 0 ) sc->type ^= S_FLAT; if ( mesh->ne == 0 ) sc->item |= S_GEOM; /* compute scene depth */ sc->dmax = sc->dmin= mesh->xmax - mesh->xmin; sc->dmax = max(sc->dmax,mesh->ymax - mesh->ymin); sc->dmin = min(sc->dmin,mesh->ymax - mesh->ymin); if ( mesh->dim == 3 ) { sc->dmax = max(sc->dmax,mesh->zmax - mesh->zmin); sc->dmin = min(sc->dmin,mesh->zmax - mesh->zmin); } sc->dmax = fabs(sc->dmax); sc->dmin = fabs(sc->dmin); if ( !sc->par.sunp ) { sc->par.sunpos[0] *= 2.0*sc->dmax; sc->par.sunpos[1] *= 2.0*sc->dmax; sc->par.sunpos[2] *= 2.0*sc->dmax; } sc->par.sunpos[3] = 1.0; /* create window */ glutInitWindowSize(sc->par.xs,sc->par.ys); sc->idwin = glutCreateWindow(""); assert(sc->idwin != 0); if ( fullscreen ) { glutFullScreen(); sc->par.xs = glutGet(GLUT_SCREEN_WIDTH); sc->par.ys = glutGet(GLUT_SCREEN_HEIGHT); } /* set window name */ sprintf(data,"Medit - [%s] #%d",mesh->name,sc->idwin); glutSetWindowTitle(data); glutSetIconTitle(data); /* required! to change background color */ glClearColor(sc->par.back[0],sc->par.back[1], sc->par.back[2],sc->par.back[3]); /* init perspective */ sc->persp = initPersp(0,sc->dmax); sc->camera = (pCamera)initCamera(sc,Y_AXIS); if ( mesh->typ == 2 ) { sc->persp->pmode = CAMERA; sc->persp->depth *= 0.5; } /* create default view */ sc->view = (pTransform)createTransform(); if ( !sc->view ) return(0); sc->type |= S_RESET + S_DECO; sc->clip = (pClip)createClip(sc,mesh); if ( !sc->clip ) return(0); sc->cube = (pCube)createCube(sc,mesh); if ( !sc->cube ) return(0); /* create menus */ if ( !createMenus(sc,mesh) ) return(0); /* assign callbacks */ if ( sc->type & S_SCISSOR) glutDisplayFunc(scissorScene); else if ( option == SCHNAUZER ) glutDisplayFunc(redrawSchnauzer); else if ( sc->persp->pmode == CAMERA ) { glutMouseFunc(mouseCamera); glutMotionFunc(motionCamera); glutDisplayFunc(redrawScene); } else { glutMouseFunc(mouse); glutMotionFunc(motion); glutDisplayFunc(redrawScene); } glutReshapeFunc(reshapeScene); glutKeyboardFunc(keyScene); glutSpecialFunc(special); glutAttachMenu(GLUT_RIGHT_BUTTON); /* create display lists by geom type */ glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); doLists(sc,mesh); sc->glist = geomList(sc,mesh); sc->type |= S_FOLLOW; /* local stack */ if ( !pilmat ) { pilmat = (int*)calloc(sc->par.nbmat+2,sizeof(int)); if ( !pilmat ) return(0); } /* color list */ setupPalette(sc,mesh); sc->stream = NULL; initGrafix(sc,mesh); return(1);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?