📄 editor.c
字号:
voidYACME_makeMenu(void){ YACME_edit_menu = glutCreateMenu( YACME_menuFunc ); glutAddMenuEntry( "red", EDIT_RED_ITEM ); glutAddMenuEntry( "green", EDIT_GREEN_ITEM ); glutAddMenuEntry( "blue", EDIT_BLUE_ITEM ); glutAddMenuEntry( "alpha", EDIT_ALPHA_ITEM ); YACME_mode_menu = glutCreateMenu( YACME_menuFunc ); glutAddMenuEntry( "Constant ", CONSTANT_ITEM ); glutAddMenuEntry( "Linear ", LINEAR_ITEM ); glutAddMenuEntry( "Polynomial", POLYNOM_ITEM ); YACME_switch_menu = glutCreateMenu( YACME_menuFunc ); glutAddMenuEntry( "Red on", RED_ITEM ); glutAddMenuEntry( "Green on", GREEN_ITEM ); glutAddMenuEntry( "Blue on", BLUE_ITEM ); glutAddMenuEntry( "Alpha on", ALPHA_ITEM ); glutCreateMenu( YACME_menuFunc ); glutAddMenuEntry( "Manual ", MANUAL_ITEM ); glutAddMenuEntry( "Apply", APPLY_ITEM ); glutAddMenuEntry( "Reset", RESET_ITEM ); glutAddMenuEntry( "Close", CLOSE_ITEM ); glutAddSubMenu( "Mode... ", YACME_mode_menu ); glutAddSubMenu( "Switch... ", YACME_switch_menu ); glutAddSubMenu( "Edit... ", YACME_edit_menu ); glutAttachMenu( GLUT_RIGHT_BUTTON );}/*---------------------------------------------------------------------------* * YACME_menuFunc *---------------------------------------------------------------------------*/static voidYACME_menuFunc( int item ){ switch( item ) { case CLOSE_ITEM: break; case RESET_ITEM: if (applyCB) (*applyCB)(); else if (newmapCB) (*newmapCB)(); ResetCMap(); curPoint = NULL; break; case APPLY_ITEM: if (applyCB) (*applyCB)(); else if (newmapCB) (*newmapCB)(); ApplyCMap(); break; case MANUAL_ITEM: /* switch to continuous */ glutChangeToMenuEntry( 1, "Continuous", CONTINUOUS_ITEM ); YACME_refresh = CONTINUOUS; break; case CONTINUOUS_ITEM: /* switch to manual */ glutChangeToMenuEntry( 1, "Manual ", MANUAL_ITEM ); if (newmapCB) (*newmapCB)(); ApplyCMap(); YACME_refresh = MANUAL; break; case RED_ITEM: DrawCurve[0] = !DrawCurve[0]; if (DrawCurve[0]) glutChangeToMenuEntry( 1, "Red on", RED_ITEM ); else glutChangeToMenuEntry( 1, "Red off", RED_ITEM ); curPoint = NULL; break; case GREEN_ITEM: DrawCurve[1] = !DrawCurve[1]; if (DrawCurve[1]) glutChangeToMenuEntry( 2, "Green on", GREEN_ITEM ); else glutChangeToMenuEntry( 2, "Green off", GREEN_ITEM ); curPoint = NULL; break; case BLUE_ITEM: DrawCurve[2] = !DrawCurve[2]; if (DrawCurve[2]) glutChangeToMenuEntry( 3, "Blue on", BLUE_ITEM ); else glutChangeToMenuEntry( 3, "Blue off", BLUE_ITEM ); curPoint = NULL; break; case ALPHA_ITEM: DrawCurve[3] = !DrawCurve[3]; if (DrawCurve[3]) glutChangeToMenuEntry( 4, "Alpha on", ALPHA_ITEM ); else glutChangeToMenuEntry( 4, "Alpha off", ALPHA_ITEM ); curPoint = NULL; break; case CONSTANT_ITEM: if (curPoint != NULL) { update = 1; curPoint->mode = CONSTANT; } break; case LINEAR_ITEM: if (curPoint != NULL) { update = 1; curPoint->mode = LINEAR; } break; case POLYNOM_ITEM: if (curPoint != NULL) { update = 1; curPoint->mode = POLYNOMIAL; } break; case EDIT_RED_ITEM: case EDIT_GREEN_ITEM: case EDIT_BLUE_ITEM: case EDIT_ALPHA_ITEM: curCmpnt = item-30; curPoint = userPoint[curCmpnt]; break; } glutPostRedisplay();}/*---------------------------------------------------------------------------* * output *---------------------------------------------------------------------------*/static voidoutput( float x, float y, char *string ){ int len, i; glRasterPos2f(x, y); len = (int) strlen(string); for (i = 0; i < len; i++) { glutBitmapCharacter(GLUT_BITMAP_8_BY_13, string[i]); }}/*---------------------------------------------------------------------------* * Redraw *---------------------------------------------------------------------------*/static voidRedraw( void ){ int i, j, ndx, cmpnt, priority[4]; Tangente *tg; UserPoint *upoint; char string[256]; if (update) { modifiedCurve[curCmpnt] = 1; YACME_update( curCmpnt, curPoint ); if ( newmapCB && (YACME_refresh == CONTINUOUS)) (*newmapCB)(); update = 0; } glClear( GL_COLOR_BUFFER_BIT );/* Barettes representant la table des couleurs -------------------------------------------*/ glBegin( GL_TRIANGLE_STRIP ); glColor3f(TabCmpnt(0,0), TabCmpnt(1,0), TabCmpnt(2,0)); glVertex2f( 0., 270.*LUTRATIO ); glVertex2f( 0., 310.*LUTRATIO ); glVertex2f( .5, 270.*LUTRATIO ); glVertex2f( .5, 310.*LUTRATIO ); glEnd(); for ( i=1; i<MAXNDX; i++ ) { float x=(float)i - .5; glBegin( GL_TRIANGLE_STRIP ); glColor3f(TabCmpnt(0,i), TabCmpnt(1,i), TabCmpnt(2,i)); glVertex2f( x, 270.*LUTRATIO ); glVertex2f( x, 310.*LUTRATIO ); glVertex2f( x+1., 270.*LUTRATIO ); glVertex2f( x+1., 310.*LUTRATIO ); glEnd(); } glBegin( GL_TRIANGLE_STRIP ); glColor3f(TabCmpnt(0,MAXNDX), TabCmpnt(1,MAXNDX), TabCmpnt(2,MAXNDX)); glVertex2f( (float)MAXNDX-.5, 270.*LUTRATIO ); glVertex2f( (float)MAXNDX-.5, 310.*LUTRATIO ); glVertex2f( (float)MAXNDX, 270.*LUTRATIO ); glVertex2f( (float)MAXNDX, 310.*LUTRATIO ); glEnd();/* Graphe y = cpste(x) -------------------*/ glColor3f(0.,0.,0.); glBegin( GL_TRIANGLE_STRIP ); glVertex2f( 0., 0. ); glVertex2f( (float) MAXNDX, 0. ); glVertex2f( 0., (float) MAXNDX ); glVertex2f( (float) MAXNDX, (float) MAXNDX ); glEnd();/* Curves y = cpste(x) --------------------*/ for ( i=0; i<curCmpnt; i++) { priority[i] = i; } for ( i=curCmpnt+1; i<4; i++ ) { priority[i-1] = i; } priority[3] = curCmpnt; cmpnt = priority[0]; for ( i=0; i<4; i++, cmpnt=priority[i] ) if ( DrawCurve[cmpnt] ) { switch (cmpnt) { case 3: glColor3f(1.,1.,1.); break; case 2: glColor3f(0.,0.,1.); break; case 1: glColor3f(0.,1.,0.); break; case 0: glColor3f(1.,0.,0.); break; } for ( j=0; j<MAXNDX; j++ ) { glBegin( GL_LINES ); glVertex2f( (float)j, (float)MAXNDX*TabCmpnt(cmpnt,j) ); glVertex2f( (float)(j+1), (float)MAXNDX*TabCmpnt(cmpnt,j+1) ); glEnd(); } } if ( curPoint != NULL ) { float h;/* user defined points -------------------*/ upoint = userPoint[curCmpnt]; do {/* Point -----*/#define DIMPOINT (2.*LUTRATIO) glBegin( GL_TRIANGLE_STRIP ); glVertex2f( upoint->x-DIMPOINT, upoint->y-DIMPOINT ); glVertex2f( upoint->x-DIMPOINT, upoint->y+DIMPOINT ); glVertex2f( upoint->x+DIMPOINT, upoint->y-DIMPOINT ); glVertex2f( upoint->x+DIMPOINT, upoint->y+DIMPOINT ); glEnd();/* Tangente --------*/ tg = &upoint->tg; if (upoint->last ? upoint->last->mode == POLYNOMIAL : 0) { glBegin( GL_LINES ); glVertex2f( tg->x0, tg->y0 ); glVertex2f( upoint->x, upoint->y ); glEnd(); glBegin( GL_LINE_LOOP ); glVertex2f( tg->x0-DIMPOINT, tg->y0-DIMPOINT ); glVertex2f( tg->x0-DIMPOINT, tg->y0+DIMPOINT ); glVertex2f( tg->x0+DIMPOINT, tg->y0+DIMPOINT ); glVertex2f( tg->x0+DIMPOINT, tg->y0-DIMPOINT ); glEnd(); } if (upoint->mode == POLYNOMIAL) { glBegin( GL_LINES ); glVertex2f( upoint->x, upoint->y ); glVertex2f( tg->x1, tg->y1 ); glEnd(); glBegin( GL_LINE_LOOP ); glVertex2f( tg->x1-DIMPOINT, tg->y1-DIMPOINT ); glVertex2f( tg->x1-DIMPOINT, tg->y1+DIMPOINT ); glVertex2f( tg->x1+DIMPOINT, tg->y1+DIMPOINT ); glVertex2f( tg->x1+DIMPOINT, tg->y1-DIMPOINT ); glEnd(); } } while ( (upoint=upoint->next) != NULL );/* Highlight current point -----------------------*/ ndx = curPoint->x; h = curPoint->y; switch (curCmpnt) { case 3: glColor3f(1.,1.,1.); break; case 2: glColor3f(0.,0.,1.); break; case 1: glColor3f(0.,1.,0.); break; case 0: glColor3f(1.,0.,0.); break; } glBegin( GL_LINE_LOOP ); glVertex2f( (float)ndx-2.*DIMPOINT, h-2.*DIMPOINT ); glVertex2f( (float)ndx-2.*DIMPOINT, h+2.*DIMPOINT ); glVertex2f( (float)ndx+2.*DIMPOINT, h+2.*DIMPOINT ); glVertex2f( (float)ndx+2.*DIMPOINT, h-2.*DIMPOINT ); glEnd(); } else { float x, y; OrthoTransform( Mousex, Mousey, &x, &y ); ndx = (int) SUP( INF(x,(float)MAXNDX), 0 ); }/* Coordinates text string -----------------------*/ glColor3f( 0., 0., 0. ); sprintf( string, "%.5d: rgba %.3f %.3f %.3f %.3f", ndx, TabCmpnt(0,ndx), TabCmpnt(1,ndx), TabCmpnt(2,ndx), TabCmpnt(3,ndx) ); output( LUTRATIO, 257.*LUTRATIO, string ); glutSwapBuffers();}/*---------------------------------------------------------------------------* * YACME_pick *---------------------------------------------------------------------------*/voidYACME_pick( int mousex, int mousey, PickObject *obj ){ int cmpnt, i, priority[4]; float x, y, val; Tangente *tg; UserPoint *upoint; float pickrad; obj->type = -1; OrthoTransform( mousex, mousey, &x, &y );/* On travaille en priorite sur les objets definis par l'utilisateur -----------------------------------------------------------------*/ for ( i=0; i<curCmpnt; i++) { priority[i] = i; } for ( i=curCmpnt+1; i<4; i++ ) { priority[i-1] = i; } priority[3] = curCmpnt; pickrad = 3.*LUTRATIO; cmpnt = priority[3]; for ( i=3; i>=0; i--, cmpnt=priority[i] ) if ( DrawCurve[cmpnt] ) { upoint = userPoint[cmpnt]; while ( upoint != NULL ) {/* On cherche le POINT*/ if ( ABS(y-upoint->y) < pickrad && ABS(x-upoint->x) < pickrad ) { obj->upoint = upoint; obj->cmpnt = cmpnt; obj->type = POINT; return; }/* On cherche la demi-tangente GAUCHE*/ tg = &upoint->tg; if ( ABS(x-tg->x0) < pickrad && ABS(y-tg->y0) < pickrad ) { obj->upoint = upoint; obj->cmpnt = cmpnt; obj->type = LEFT_TAN; return; }/* On cherche la demi-tangente DROITE*/ if ( ABS(x-tg->x1) < pickrad && ABS(y-tg->y1) < pickrad ) { obj->upoint = upoint; obj->cmpnt = cmpnt; obj->type = RIGHT_TAN; return; } upoint = upoint->next; }/* Puis on cherche les coordonnees sur la CURVE (On considere la precision suffisante pour le picking suivant l'axe X) Remarque : on ne sort pas en ce cas, car la priorite est sur les objets utilisateurs.*/ upoint = userPoint[cmpnt]; while ( upoint->next->x < x ) { upoint = upoint->next; if ( upoint->next == NULL ) return; } val = INF( SUP( Polynome4(x,upoint->polynome), 0.), (float)MAXNDX ); if ( ABS(y-val) < pickrad ) { obj->cmpnt = cmpnt; obj->ndx = ((x-(int)x)<.5) ? (int)x : (int)x+1; obj->type = CURVE; return; } }}/*---------------------------------------------------------------------------* * YACME_update *---------------------------------------------------------------------------*/voidYACME_update( int cmpnt, UserPoint *upoint ){ int i; float val, t0, t1; Tangente *tg; tg = &upoint->tg; if ( tg->x1 != tg->x0 ) { t0 = (tg->y1-tg->y0) / (tg->x1-tg->x0); } else { t0 = (tg->y1-tg->y0)*10000.; } TabCmpnt(cmpnt,(int) upoint->x) = upoint->y/(float)MAXNDX; if ( upoint->last != NULL ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -