/*Example colored.c
Edit the colormap and display the results in the graphics window.
This program works on any 3d adapter. */
#include <gl/gl.h> #include <gl/device.h>
#define START 64 #define CURRENTCOLOR 63 #define BARWIDTH 67 #define REDBAR 934 #define GREENBAR 800 #define BLUEBAR 666 #define STARTBAR 250 #define ENDBAR 1082 #define indextovalue(index) (4*index + 3)
short redindex = 0, greenindex = 0, blueindex = 0; short whichbar(); long xorg,yorg,xsize,ysize; long redbar,greenbar,bluebar; long startbar,endbar;
main() { short index, val; Device xpos, ypos; initialize(); while (TRUE) { switch (qread(&val)) { case ESCKEY: greset(); gexit(); exit(0); case REDRAW: reshapeviewport(); getwindowsize(); buildmap(); displaymap(); break; case LEFTMOUSE: if (val){ qread(&xpos); qread(&ypos); qread(&val); qread(&val); qread(&val); if (insideport(xpos,ypos)) { index = -1; switch (whichbar(xpos,ypos,&index)) { case 0: redindex = index; break; case 1: greenindex = index; break; case 2: blueindex = index; break; default: break; }
if (index != -1) { buildmap(); displaymap(); } } } break; } }
}
initialize() { int gid;
prefposition(10, XMAXSCREEN-10, 10, YMAXSCREEN-20); keepaspect(5,4); gid = winopen("colored"); ortho2(-0.5, (float)XMAXSCREEN-0.5, -0.5, (float)YMAXSCREEN-0.5); color(0); clear(); mapcolor(CURRENTCOLOR, 0, 0, 0); qdevice(LEFTMOUSE); tie(LEFTMOUSE, MOUSEX, MOUSEY); qdevice(ESCKEY); qdevice(REDRAW); qenter(REDRAW,gid); }
getwindowsize() { getorigin(&xorg,&yorg); getsize(&xsize,&ysize); redbar = ((REDBAR * ysize) / YMAXSCREEN) + yorg; greenbar = ((GREENBAR * ysize) / YMAXSCREEN) + yorg; bluebar = ((BLUEBAR * ysize) / YMAXSCREEN) + yorg; startbar = ((STARTBAR * xsize) / XMAXSCREEN) + xorg; endbar = ((ENDBAR * xsize) / XMAXSCREEN) + xorg; }
buildmap() { register i, j; for (i = 0; i < 3; i++) { for (j = 0; j < 64; j++) { switch (i) { case 0: /* red */ mapcolor(START+i*64+j, indextovalue(j), indextovalue(greenindex), indextovalue(blueindex)); break; case 1: /* green */ mapcolor(START+i*64+j, indextovalue(redindex), indextovalue(j), indextovalue(blueindex)); break; case 2: /* blue */ mapcolor(START+i*64+j, indextovalue(redindex), indextovalue(greenindex), indextovalue(j)); break; }
}
}
mapcolor(CURRENTCOLOR, indextovalue(redindex), indextovalue(greenindex), indextovalue(blueindex)); }
displaymap() { register i, j; char redstr[10], greenstr[10], bluestr[10]; color(BLACK); clear(); for (i = 0; i < 3; i++) for (j = 0; j < 64; j++) { color(START+i*64 + j); rectfi(250 + 13*j, 934 - i*133, 263 + 13*j, 867 - i*133); color(WHITE); recti(250 + 13*j, 934 - i*133, 263 + 13*j, 867 - i*133); }
color(CURRENTCOLOR); rectfi(500, 267, 750, 400); color(WHITE); recti(500, 267, 750, 400); cmov2i(186, 894); charstr("RED"); cmov2i(186, 760); charstr("GREEN"); cmov2i(186, 627); charstr("BLUE"); cmov2i(343, 327); charstr("CURRENT COLOR"); cmov2i(475, 133); charstr("Left mouse button: choose a color"); cmov2i(475, 112); charstr("Escape key : exit"); move2i(startbar + 13*redindex, 934); draw2i(startbar + 13*redindex, 960); cmov2i(startbar + 6 + 13*redindex, 940); sprintf(redstr, "%d", indextovalue(redindex)); charstr(redstr); move2i(startbar + 13*greenindex, 800); draw2i(startbar + 13*greenindex, 827); cmov2i(startbar + 6 + 13*greenindex, 806); sprintf(greenstr, "%d", indextovalue(greenindex)); charstr(greenstr); move2i(startbar + 13*blueindex, 666); draw2i(startbar + 13*blueindex, 694); cmov2i(startbar + 6 + 13*blueindex, 674); sprintf(bluestr, "%d", indextovalue(blueindex)); charstr(bluestr); cmov2i(563, 414); charstr("("); charstr(redstr); charstr(", "); charstr(greenstr); charstr(", "); charstr(bluestr); charstr(")"); }
/* return 1 if the position of the cursor is within the window */ insideport(x,y) int x, y; { if(x<xorg) return 0; if(x>(xorg+xsize)) return 0; if(y<yorg) return 0; if(y>(yorg+ysize)) return 0; return 1; } /* returns 0 if in the redbar, 1 if in the greenbar and 2 if in the blue bar */ short whichbar(xpos,ypos,index) long xpos,ypos; short *index; { short i; i = -1; if (redbar - BARWIDTH <= ypos && ypos <= redbar) /* red color bar */ i = 0; else if (greenbar-BARWIDTH <= ypos && ypos <= greenbar) /* green color bar */ i = 1; else if (bluebar - BARWIDTH <= ypos && ypos <= bluebar) /* blue color bar */ i = 2; if (i != -1) { if (startbar <= xpos && xpos < endbar) { *index = (xpos - startbar)/13; return(i); }
} return(-1);
} /* Changes: - Added the define of start. Before this addition this program did not work on a gl adapter with an 8-bit color table #define START 512 change to: #define START 64 - Changed the CURRENTCOLOR to 63 Keep in mind that this program will alter the colormap and it does not put it back the way it was before - The comments at the beginning of the documentation are incorrect. The way that the program was before this program only worked on a machine with at least a 10-bit color look up table. */
The keepaspect subroutine, mapcolor subroutine, prefposition subroutine, setlinestyle subroutine, wincontraints subroutine, winopen subroutine.