⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 editor.c

📁 嵌入式GUI OpenGL源代码。OpenGL是嵌入式开发中常用的一种GUI系统。
💻 C
📖 第 1 页 / 共 3 页
字号:
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 + -