00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #define GLX_GLXEXT_PROTOTYPES
00018
00019 #include <glh/glh_extensions.h>
00020
00021 #include <GL/gl.h>
00022 #include <math.h>
00023 #include <stdlib.h>
00024 #include <stdio.h>
00025
00026 #include "transferEdit.h"
00027
00028 #define MAX(a,b) ((a) > (b) ? (a) : (b))
00029 #define MIN(a,b) ((a) < (b) ? (a) : (b))
00030
00031 #define BOXSIZE 8
00032
00033 #define CONST_VAL 20
00034 #define SHIFT_VAL_STEP 4
00035
00036 DataTypeTE **dataTE;
00037
00038 int focus;
00039 int hidden;
00040 int drawOffsetX;
00041 int drawOffsetY;
00042 GLint viewport[4];
00043 int *activeCh;
00044 GLfloat colorTE[5][3] = {
00045 {1., 0., 0.},
00046 {0., 1., 0.},
00047 {0., 0., 1.},
00048 {1., 1., 1.},
00049 {0., 1., 1.}
00050 };
00051 int lastMpos[2];
00052
00053 void initTE()
00054 {
00055 int idx, idi;
00056
00057 if (! (dataTE = (DataTypeTE **)malloc(NUM_TE * sizeof(DataTypeTE *)))) {
00058 fprintf(stderr, "not enough memory for transfer editor data\n");
00059 exit(1);
00060 }
00061 if (! (activeCh = (int *)malloc(NUM_TE * sizeof(int)))) {
00062 fprintf(stderr, "not enough memory for active channels\n");
00063 exit(1);
00064 }
00065
00066 for (idx = 0; idx < NUM_TE; idx++) {
00067 if (! (dataTE[idx] = (DataTypeTE *)malloc(NUM_TE_ENTRIES *
00068 sizeof(DataTypeTE)))) {
00069 fprintf(stderr, "not enough memory for transfer editor data\n");
00070 exit(1);
00071 }
00072 activeCh[idx] = 1;
00073 }
00074
00075
00076 for (idx = 0; idx < NUM_TE; idx++) {
00077 for (idi = 0; idi < NUM_TE_ENTRIES; idi++) {
00078 #if 1
00079
00080 if (idx < 4) {
00081 dataTE[idx][idi] = (DataTypeTE)idi;
00082 } else {
00083 dataTE[idx][idi] = (DataTypeTE)128;
00084 }
00085 #else
00086 dataTE[idx][idi] = (float)rand()/RAND_MAX * (NUM_TE_ENTRIES - 1);
00087 #endif
00088 }
00089 }
00090
00091 drawOffsetX = 10;
00092 drawOffsetY = 10;
00093 hidden = 1;
00094 focus = 0;
00095
00096 glGetIntegerv(GL_VIEWPORT, viewport);
00097 }
00098
00099 void destTE()
00100 {
00101 int idx;
00102
00103 for (idx = 0; idx < NUM_TE; idx++) {
00104 if (dataTE[idx] != 0)
00105 free(dataTE[idx]);
00106 }
00107 free(dataTE);
00108 free(activeCh);
00109 }
00110
00111 void drawTE()
00112 {
00113 int idx, idi;
00114
00115 if (hidden)
00116 return;
00117
00118 glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT);
00119
00120 glMatrixMode(GL_PROJECTION);
00121 glPushMatrix();
00122 glLoadIdentity();
00123 glOrtho(0, viewport[2], 0, viewport[3], -1., 1.);
00124
00125 glMatrixMode(GL_MODELVIEW);
00126 glPushMatrix();
00127 glLoadIdentity();
00128 glTranslatef((GLfloat)drawOffsetX, (GLfloat)drawOffsetY, 0.0f);
00129
00130 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00131 glEnable(GL_BLEND);
00132 glBegin(GL_QUADS);
00133 glColor4f(0.0f, 0.0f, 0.0f, 0.2f);
00134 glVertex2f(0.0f, 0.0f);
00135 glVertex2f(255.0f, 0.0f);
00136 glVertex2f(255.0f, 255.0f);
00137 glVertex2f(0.0f, 255.0f);
00138 glEnd();
00139
00140 glBegin(GL_QUADS);
00141 for (idx = 0; idx < NUM_TE; idx++) {
00142 if (activeCh[idx]) {
00143 glColor3fv(colorTE[idx]);
00144
00145 glVertex2i(idx * 2 * BOXSIZE + BOXSIZE, 8);
00146 glVertex2i(idx * 2 * BOXSIZE + 2 * BOXSIZE, 8);
00147 glVertex2i(idx * 2 * BOXSIZE + 2 * BOXSIZE, 8 + BOXSIZE);
00148 glVertex2i(idx * 2 * BOXSIZE + BOXSIZE, 8 + BOXSIZE);
00149 }
00150 }
00151 glEnd();
00152
00153 glDisable(GL_BLEND);
00154
00155 for (idx = 0; idx < NUM_TE; idx++) {
00156 glBegin(GL_LINE_STRIP);
00157 glColor3fv(colorTE[idx]);
00158 for (idi = 0; idi < NUM_TE_ENTRIES; idi++)
00159 glVertex2i(idi, dataTE[idx][idi]);
00160 glEnd();
00161 }
00162
00163 glPopMatrix();
00164 glMatrixMode(GL_PROJECTION);
00165 glPopMatrix();
00166
00167 glPopAttrib();
00168 }
00169
00170 int mouseIsInside(int x, int y)
00171 {
00172 return (((drawOffsetX <= x) && (x <= drawOffsetX + NUM_TE_ENTRIES)) &&
00173 ((drawOffsetY <= y) && (y <= drawOffsetY + NUM_TE_ENTRIES)));
00174 }
00175
00176 int mouseTE(int x, int y)
00177 {
00178 if ((hidden) || (!mouseIsInside(x, viewport[3] - y))) {
00179 focus = 0;
00180 return 0;
00181 }
00182
00183 lastMpos[0] = x - drawOffsetX;
00184 lastMpos[1] = viewport[3] - (y + drawOffsetY);
00185 focus = 1;
00186 return 1;
00187 }
00188
00189 int motionTE(int x, int y)
00190 {
00191 int actuMpos[2], startY, i, idt;
00192 float m;
00193
00194 if ((hidden) || (!focus))
00195 return 0;
00196
00197 actuMpos[0] = x - drawOffsetX;
00198 actuMpos[1] = viewport[3] - (y + drawOffsetY);
00199
00200
00201 for( i = 0; i < 2; i++) {
00202 if (actuMpos[i] < 0) actuMpos[i] = 0;
00203 if (actuMpos[i] > (NUM_TE_ENTRIES-1)) actuMpos[i] = NUM_TE_ENTRIES-1;
00204 }
00205
00206 if (actuMpos[0] < lastMpos[0]) {
00207 m = (lastMpos[1] - actuMpos[1]) / (float) (lastMpos[0] -
00208 actuMpos[0]);
00209 startY = actuMpos[1];
00210 } else {
00211 m = (actuMpos[1] - lastMpos[1]) / (float) (actuMpos[0] -
00212 lastMpos[0]);
00213 startY = lastMpos[1];
00214 }
00215
00216 for (idt = 0; idt < NUM_TE; idt++) {
00217 if (activeCh[idt]) {
00218 int idx;
00219 for (idx = 0; idx <= abs(actuMpos[0] - lastMpos[0]); idx++)
00220 dataTE[idt][MIN(actuMpos[0], lastMpos[0]) + idx] =
00221 (DataTypeTE)(startY + (int) floor(idx * m));
00222 }
00223 }
00224 lastMpos[0] = actuMpos[0];
00225 lastMpos[1] = actuMpos[1];
00226
00227 return 1;
00228 }
00229
00230 void setIdentity()
00231 {
00232 int i, j;
00233 for (i = 0; i < NUM_TE_ENTRIES; i++) {
00234 for (j = 0; j < NUM_TE; j++) {
00235 if (activeCh[j]) dataTE[j][i] = (DataTypeTE)i;
00236 }
00237 }
00238 }
00239
00240 void setInvert()
00241 {
00242 int i, j;
00243 for (i = 0; i < NUM_TE_ENTRIES; i++) {
00244 for (j = 0; j < NUM_TE; j++) {
00245 if (activeCh[j]) dataTE[j][i] = NUM_TE_ENTRIES-1-dataTE[j][i];
00246 }
00247 }
00248 }
00249
00250 void setConst(void)
00251 {
00252 int i, j;
00253
00254 for (i = 0; i < NUM_TE_ENTRIES; i++) {
00255 for (j = 0; j < NUM_TE; j++) {
00256 if (activeCh[j]) {
00257 dataTE[j][i] = CONST_VAL;
00258 }
00259 }
00260 }
00261 }
00262
00263 void shiftFunc(int delta)
00264 {
00265 int i, j, temp;
00266
00267 for (i = 0; i < NUM_TE_ENTRIES; i++) {
00268 for (j = 0; j < NUM_TE; j++) {
00269 if (activeCh[j]) {
00270 temp = dataTE[j][i] + delta;
00271 if (temp < 0) {
00272 dataTE[j][i] = 0;
00273 } else if (temp > 255) {
00274 dataTE[j][i] = 255;
00275 } else {
00276 dataTE[j][i] = (DataTypeTE)temp;
00277 }
00278 }
00279 }
00280 }
00281 }
00282
00283 int keyTE(unsigned char k, int x, int y)
00284 {
00285 if ((hidden) || (!mouseIsInside(x, viewport[3] - y)))
00286 return 0;
00287
00288 switch (k) {
00289 case 'r':
00290 activeCh[0] = !activeCh[0];
00291 break;
00292 case 'g':
00293 activeCh[1] = !activeCh[1];
00294 break;
00295 case 'b':
00296 activeCh[2] = !activeCh[2];
00297 break;
00298 case 'a':
00299 activeCh[3] = !activeCh[3];
00300 break;
00301 case 'o':
00302 activeCh[4] = !activeCh[4];
00303 break;
00304 case 't':
00305 toggleHidden();
00306 break;
00307 case 'i':
00308 setIdentity();
00309 break;
00310 case 'm':
00311 setInvert();
00312 break;
00313 case 'c':
00314 setConst();
00315 break;
00316 case 'h':
00317 shiftFunc(SHIFT_VAL_STEP);
00318 break;
00319 case 'n':
00320 shiftFunc(-SHIFT_VAL_STEP);
00321 break;
00322 default:
00323 return 0;
00324 }
00325
00326 return 1;
00327 }
00328
00329 void setOffsets(int offsetX, int offsetY)
00330 {
00331 drawOffsetX = offsetX;
00332 drawOffsetY = offsetY;
00333 }
00334
00335 void setHidden(int h)
00336 {
00337 hidden = h;
00338 }
00339
00340 void toggleHidden()
00341 {
00342 hidden = !hidden;
00343 }
00344
00345 void resizeTE()
00346 {
00347 glGetIntegerv(GL_VIEWPORT, viewport);
00348 }
00349
00350 DataTypeTE **getDataTE(void)
00351 {
00352 return dataTE;
00353 }