/*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.