📄 editor.c
字号:
void
YACME_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 void
YACME_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 void
output( 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 void
Redraw( 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
*---------------------------------------------------------------------------*/
void
YACME_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
*---------------------------------------------------------------------------*/
void
YACME_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 + -