📄 editor.c
字号:
/*===========================================================================* * * YACME * Yet Another ColorMap Editor * * Patrick BOUCHAUD - 1993 * SGI Switzerland * * Converted to OpenGL using GLUT * *===========================================================================*/#include <stdio.h>#include <string.h>#include <stdlib.h>#include <math.h>#include <GL/glut.h>#include "mallocbis.h"/* For portability... */#undef fsqrt#define fsqrt(_a) sqrt(_a)#define SUP(a,b) ( ((a)>(b)) ? (a) : (b) )#define INF(a,b) ( ((a)<(b)) ? (a) : (b) )#define ABS(a) ( ((a)<0) ? -(a) : (a) )#define POINT 1#define CURVE 2#define LEFT_TAN 3#define RIGHT_TAN 4#define MANUAL 1#define CONTINUOUS 2#define CONSTANT 1#define LINEAR 2#define POLYNOMIAL 3#define TabCmpnt(c,n) TabCmpnt[(n)*4+(c)]#define MAXNDX (dimlut-1)#define WINHEIGHT 381#define WINWIDTH 318#define LUTRATIO ((float)MAXNDX/255.)#define LEFT LUTRATIO*(-5.)#define RIGHT LUTRATIO*(260.)#define BOTTOM LUTRATIO*(-5.)#define TOP LUTRATIO*(315.)#define TANLEN LUTRATIO*(25.)typedef float Matrix[4][4];typedef struct { float x0, y0, x1, y1;} Tangente;typedef struct UserPointStruct { float x, y; Tangente tg; int mode; float polynome[4]; struct UserPointStruct *next, *last;} UserPoint;void ResetCMap(void);void ApplyCMap(void);void YACME_makeMenu(void);extern void invertmat(float from[4][4], float to[4][4]);static UserPoint *FreePointList = NULL;#define newPoint( point ) newItem( point, FreePointList, UserPoint )#define freePoint( point ) freeItem( point, FreePointList )typedef struct { int type, cmpnt, ndx; UserPoint *upoint;} PickObject;struct { int leftdown, middledown, rightdown;} mouse;void YACME_pick( int mx, int my, PickObject *obj );void YACME_update( int cmpnt, UserPoint *upoint );int YACME_get( unsigned long *table );void DeletePoint( int cmpnt, UserPoint *upoint );int MovePoint( int, int );int MoveTangente( int, int, int );int InsertPoint( PickObject *obj );void GetPolynome( int mode, float a0, float b0, float t0, float a1, float b1, float t1, float coeff[4] );void OrthoTransform( int mx, int my, float *x, float *y );float Polynome4( float x, float *polynome );static int DrawCurve[4] = { 1, 1, 1, 1, }, modifiedCurve[4] = { 1, 1, 1, 1 }, YACME_refresh = MANUAL, curCmpnt = 0, curType = 0, Mousex, Mousey;static float *TabCmpnt;static int YACME_switch_menu = 0, YACME_mode_menu, YACME_edit_menu;static int YACME_win = 0, W, H , update = 0;static UserPoint *userPoint[4], *userPointSvg[4], *curPoint = NULL;static void Redraw( void );static void Reshape( int, int );static void Mouse( int, int, int, int );static void Motion( int, int );static void Key( unsigned char, int, int );static void Special( int, int, int );static void YACME_menuFunc( int );typedef void (*CallBack)(void);static CallBack newmapCB, applyCB;static int dimlut;/*---------------------------------------------------------------------------* * YACME_init *---------------------------------------------------------------------------*/voidYACME_init( int x, int y, int w, int h, int dim, float **list, CallBack newmapFunc, CallBack applyFunc){ int i, j; UserPoint *userpoint; if (YACME_win) return; dimlut = dim; newmapCB = newmapFunc; applyCB = applyFunc; if (*list==NULL) { *list = TabCmpnt = (float *) malloc( 4*dimlut*sizeof(float) ); for (i=0; i<4; i++) { newPoint( userPoint[i] ); userpoint = userPoint[i]; userpoint->mode = POLYNOMIAL; userpoint->x = 0.; userpoint->y = 0.; userpoint->last = NULL; userpoint->tg.x0 = 0.; userpoint->tg.y0 = 0.; userpoint->tg.x1 = TANLEN; userpoint->tg.y1 = 0.; newPoint( userpoint->next ); userpoint = userpoint->next; userpoint->mode = POLYNOMIAL; userpoint->x = (float)MAXNDX; userpoint->y = (float)MAXNDX; userpoint->last = userPoint[i]; userpoint->next = NULL; userpoint->tg.x0 = (float)(MAXNDX-TANLEN); userpoint->tg.y0 = (float)MAXNDX; userpoint->tg.x1 = (float)MAXNDX; userpoint->tg.y1 = (float)MAXNDX; } } else { UserPoint *upoint[4], *lastupoint[4]={0,0,0,0}; TabCmpnt = *list; for (i=0; i<dim; i++) { for (j=0; j<4; j++) { if (i==0) { newPoint( userPoint[j] ); upoint[j] = userPoint[j]; } else { newPoint( upoint[j]->next ); upoint[j] = upoint[j]->next; } upoint[j]->next = NULL; upoint[j]->last = lastupoint[j]; upoint[j]->mode = LINEAR; upoint[j]->x = (float)i; upoint[j]->y = (float)MAXNDX*TabCmpnt(j,i); if (i==0) { upoint[j]->tg.x0 = 0.; upoint[j]->tg.y0 = 0.; upoint[j]->tg.x1 = TANLEN; upoint[j]->tg.y1 = 0.; } else { float slope = upoint[j]->y - upoint[j]->last->y, dx = TANLEN/fsqrt(slope*slope + 1), dy = slope*dx; upoint[j]->tg.x0 = upoint[j]->x - dx; upoint[j]->tg.y0 = upoint[j]->y - dy; upoint[j]->tg.x1 = upoint[j]->x + dx; upoint[j]->tg.y1 = upoint[j]->y + dy; } lastupoint[j] = upoint[j]; } } }/* TabComponents update --------------------*/ for (i=0; i<4; i++) { for (userpoint=userPoint[i]; userpoint!=NULL; userpoint=userpoint->next) YACME_update( i, userpoint ); } ApplyCMap(); if (!YACME_win) { glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE ); glutInitWindowPosition( x, y ); glutInitWindowSize( w, h ); YACME_win = glutCreateWindow( "LUT editor" ); glutDisplayFunc( Redraw ); glutReshapeFunc( Reshape ); glutMouseFunc( Mouse ); glutMotionFunc( Motion ); glutPassiveMotionFunc( Motion ); glutSpecialFunc( Special ); glutKeyboardFunc( Key ); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); glOrtho( LEFT, RIGHT, BOTTOM, TOP, -1., 1. ); glClearColor( 0.66, 0.66, 0.66, 1. ); glClear( GL_COLOR_BUFFER_BIT ); glShadeModel( GL_FLAT ); glutSwapBuffers(); YACME_makeMenu(); }}/*---------------------------------------------------------------------------* * Key *---------------------------------------------------------------------------*//* ARGSUSED1 */static voidKey( unsigned char key, int x, int y ){ UserPoint *previousPoint; switch (key) { case 27: /* Escape */ exit(0); break; case 127: /* BackSpace */ case 8: /* Delete */ if (!curPoint) return; previousPoint = (curPoint->last ? curPoint->last : userPoint[curCmpnt]); DeletePoint( curCmpnt, curPoint ); modifiedCurve[curCmpnt] = 1; update = 1; curPoint = previousPoint; break; } glutPostRedisplay();}/*---------------------------------------------------------------------------* * Special *---------------------------------------------------------------------------*//* ARGSUSED1 */static voidSpecial( int key, int xx, int yy ){ int x, y, minx, maxx; float dx, dy; if (curPoint == NULL ) return; if (curPoint->next == NULL) return; if (curPoint->last == NULL) return; x = (int)curPoint->x; y = (int)curPoint->y; minx = (int)curPoint->last->x; minx++; maxx = (int)curPoint->next->x; maxx--; switch (key) { case GLUT_KEY_LEFT: if (x > minx) x--; break; case GLUT_KEY_RIGHT: if (x < maxx) x++; break; case GLUT_KEY_UP: if (y < MAXNDX) y++; break; case GLUT_KEY_DOWN: if (y > 0) y--; break; } dx = (float)x - curPoint->x; curPoint->x += dx; curPoint->tg.x0 += dx; curPoint->tg.x1 += dx; dy = (float)y - curPoint->y; curPoint->y = y; curPoint->tg.y0 += dy; curPoint->tg.y1 += dy; update = 1; glutPostRedisplay();}/*---------------------------------------------------------------------------* * Reshape *---------------------------------------------------------------------------*/static voidReshape( int w, int h ){ glViewport( 0, 0, w, h ); W = w; H = h; glutPostRedisplay();}/*---------------------------------------------------------------------------* * Mouse *---------------------------------------------------------------------------*/static voidMouse( int button, int state, int x, int y ){ PickObject object; y = H-y; switch (button) { case GLUT_RIGHT_BUTTON: mouse.rightdown = (state==GLUT_DOWN); break; case GLUT_MIDDLE_BUTTON: mouse.middledown = (state==GLUT_DOWN); break; case GLUT_LEFT_BUTTON: mouse.leftdown = (state==GLUT_DOWN); if (mouse.leftdown) { YACME_pick( x, y, &object ); curType = object.type; switch ( object.type ) { case CURVE: if ((curType = InsertPoint( &object ) != 0)) { curPoint = object.upoint; curCmpnt = object.cmpnt; } else curPoint = NULL; break; case POINT: case LEFT_TAN: case RIGHT_TAN: curPoint = object.upoint; curCmpnt = object.cmpnt; break; default: curPoint = NULL; } break; } } glutPostRedisplay();}/*---------------------------------------------------------------------------* * Motion *---------------------------------------------------------------------------*/static voidMotion( int x, int y ){ Mousex = x; Mousey = H-y; if (mouse.leftdown) { switch (curType) { case POINT: update = MovePoint( Mousex, Mousey ); break; case LEFT_TAN: update = MoveTangente( -1, Mousex, Mousey ); break; case RIGHT_TAN: update = MoveTangente( 1, Mousex, Mousey ); break; } } glutPostRedisplay();}/*---------------------------------------------------------------------------* * YACME_makeMenu *---------------------------------------------------------------------------*/#define CONTINUOUS_ITEM 5#define MANUAL_ITEM 4#define APPLY_ITEM 3#define RESET_ITEM 2#define CLOSE_ITEM 1#define RED_ITEM 10#define GREEN_ITEM 11#define BLUE_ITEM 12#define ALPHA_ITEM 13#define CONSTANT_ITEM 22#define LINEAR_ITEM 21#define POLYNOM_ITEM 20#define EDIT_RED_ITEM 30#define EDIT_GREEN_ITEM 31#define EDIT_BLUE_ITEM 32#define EDIT_ALPHA_ITEM 33
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -