132001f49Smrg/**
232001f49Smrg * Test rubber-band selection box w/ logicops and blend.
332001f49Smrg */
432001f49Smrg
532001f49Smrg#include <stdio.h>
632001f49Smrg#include <stdlib.h>
732001f49Smrg#include <math.h>
832001f49Smrg#include <GL/glew.h>
932001f49Smrg#include "glut_wrap.h"
1032001f49Smrg#include "readtex.c"
1132001f49Smrg
1232001f49Smrg#define IMAGE_FILE DEMOS_DATA_DIR "arch.rgb"
1332001f49Smrg
1432001f49Smrgstatic int ImgWidth, ImgHeight;
1532001f49Smrgstatic GLenum ImgFormat;
1632001f49Smrgstatic GLubyte *Image = NULL;
1732001f49Smrg
1832001f49Smrgstatic int Win;
1932001f49Smrgstatic int Width = 512, Height = 512;
2032001f49Smrg
2132001f49Smrgstruct rect
2232001f49Smrg{
2332001f49Smrg   int x0, y0, x1, y1;
2432001f49Smrg};
2532001f49Smrg
2632001f49Smrgstatic struct rect OldRect, NewRect;
2732001f49Smrg
2832001f49Smrgstatic GLboolean ButtonDown = GL_FALSE;
297ec3b29aSmrgstatic GLboolean LogicOp = GL_TRUE;
3032001f49Smrg
3132001f49Smrgstatic GLboolean RedrawBackground = GL_TRUE;
3232001f49Smrg
3332001f49Smrgstatic const GLfloat red[4] = {1.0, 0.2, 0.2, 1.0};
3432001f49Smrgstatic const GLfloat green[4] = {0.2, 1.0, 0.2, 1.0};
3532001f49Smrgstatic const GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0};
3632001f49Smrg
377ec3b29aSmrgstatic int color = 0;
387ec3b29aSmrg
3932001f49Smrg
4032001f49Smrg/*
4132001f49Smrg * Draw rubberband box in front buffer
4232001f49Smrg */
4332001f49Smrgstatic void
4432001f49SmrgDrawRect(const struct rect *r)
4532001f49Smrg{
4632001f49Smrg   glDrawBuffer(GL_FRONT);
4732001f49Smrg
4832001f49Smrg   if (LogicOp) {
4932001f49Smrg      glLogicOp(GL_XOR);
5032001f49Smrg      glEnable(GL_COLOR_LOGIC_OP);
517ec3b29aSmrg
527ec3b29aSmrg      if (color == 0)
537ec3b29aSmrg         glColor3f(1, 1, 1);
547ec3b29aSmrg      else
557ec3b29aSmrg         glColor3ub(152, 105, 58);
5632001f49Smrg   }
5732001f49Smrg   else {
5832001f49Smrg      glEnable(GL_BLEND);
5932001f49Smrg      glBlendFunc(GL_ONE, GL_ONE);
6032001f49Smrg      glBlendEquation(GL_FUNC_SUBTRACT);
617ec3b29aSmrg      glColor3f(1, 1, 1);
6232001f49Smrg   }
6332001f49Smrg
6432001f49Smrg   glBegin(GL_LINE_LOOP);
6532001f49Smrg   glVertex2i(r->x0, r->y0);
6632001f49Smrg   glVertex2i(r->x1, r->y0);
6732001f49Smrg   glVertex2i(r->x1, r->y1);
6832001f49Smrg   glVertex2i(r->x0, r->y1);
6932001f49Smrg   glEnd();
7032001f49Smrg
7132001f49Smrg   glDisable(GL_COLOR_LOGIC_OP);
7232001f49Smrg   glDisable(GL_BLEND);
7332001f49Smrg
7432001f49Smrg   /* Need this to ensure the front buffer drawing is actually displayed */
7532001f49Smrg   glFlush();
7632001f49Smrg
7732001f49Smrg   glDrawBuffer(GL_BACK);
7832001f49Smrg}
7932001f49Smrg
8032001f49Smrg
8132001f49Smrgstatic void
8232001f49SmrgPrintString(const char *s)
8332001f49Smrg{
8432001f49Smrg   while (*s) {
8532001f49Smrg      glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
8632001f49Smrg      s++;
8732001f49Smrg   }
8832001f49Smrg}
8932001f49Smrg
9032001f49Smrg
9132001f49Smrgstatic void
9232001f49SmrgDrawBackground(void)
9332001f49Smrg{
9432001f49Smrg   char s[100];
9532001f49Smrg
9632001f49Smrg   sprintf(s, "[L/B] %s mode.   Use mouse to make selection box.",
9732001f49Smrg               LogicOp ? "LogicOp" : "Blend");
9832001f49Smrg
9932001f49Smrg   glClear(GL_COLOR_BUFFER_BIT);
10032001f49Smrg
10132001f49Smrg   glWindowPos2i((Width - ImgWidth) / 2, (Height - ImgHeight) / 2);
10232001f49Smrg   glDrawPixels(ImgWidth, ImgHeight, ImgFormat, GL_UNSIGNED_BYTE, Image);
10332001f49Smrg
1047ec3b29aSmrg   glColor3f(1, 1, 1);
10532001f49Smrg   glWindowPos2i(10, 10);
10632001f49Smrg   PrintString(s);
10732001f49Smrg
10832001f49Smrg   glutSwapBuffers();
10932001f49Smrg}
11032001f49Smrg
11132001f49Smrg
11232001f49Smrgstatic void
11332001f49SmrgDraw(void)
11432001f49Smrg{
11532001f49Smrg   if (RedrawBackground) {
11632001f49Smrg      DrawBackground();
11732001f49Smrg   }
11832001f49Smrg
11932001f49Smrg   if (ButtonDown) {
12032001f49Smrg      if (!RedrawBackground)
12132001f49Smrg         DrawRect(&OldRect); /* erase old */
12232001f49Smrg
12332001f49Smrg      DrawRect(&NewRect); /* draw new */
12432001f49Smrg
12532001f49Smrg      OldRect = NewRect;
12632001f49Smrg   }
12732001f49Smrg
12832001f49Smrg   RedrawBackground = GL_FALSE;
12932001f49Smrg}
13032001f49Smrg
13132001f49Smrg
13232001f49Smrgstatic void
13332001f49SmrgReshape(int width, int height)
13432001f49Smrg{
13532001f49Smrg   Width = width;
13632001f49Smrg   Height = height;
13732001f49Smrg
13832001f49Smrg   glViewport(0, 0, width, height);
13932001f49Smrg
14032001f49Smrg   glMatrixMode(GL_PROJECTION);
14132001f49Smrg   glLoadIdentity();
14232001f49Smrg   glOrtho(0, Width, Height, 0, -1, 1); /* Inverted Y! */
14332001f49Smrg
14432001f49Smrg   glMatrixMode(GL_MODELVIEW);
14532001f49Smrg   glLoadIdentity();
14632001f49Smrg
14732001f49Smrg   RedrawBackground = GL_TRUE;
14832001f49Smrg}
14932001f49Smrg
15032001f49Smrg
15132001f49Smrgstatic void
15232001f49SmrgKey(unsigned char key, int x, int y)
15332001f49Smrg{
15432001f49Smrg   (void) x;
15532001f49Smrg   (void) y;
15632001f49Smrg   switch (key) {
1577ec3b29aSmrg   case '1':
1587ec3b29aSmrg      glLineWidth(1);
1597ec3b29aSmrg      break;
1607ec3b29aSmrg   case '2':
1617ec3b29aSmrg      glLineWidth(2);
1627ec3b29aSmrg      break;
1637ec3b29aSmrg   case '3':
1647ec3b29aSmrg      glLineWidth(3);
1657ec3b29aSmrg      break;
1667ec3b29aSmrg   case '4':
1677ec3b29aSmrg      glLineWidth(4);
1687ec3b29aSmrg      break;
16932001f49Smrg   case 'b':
17032001f49Smrg   case 'B':
17132001f49Smrg      LogicOp = GL_FALSE;
17232001f49Smrg      break;
1737ec3b29aSmrg   case 'c':
1747ec3b29aSmrg   case 'C':
1757ec3b29aSmrg      color = !color;
1767ec3b29aSmrg      printf("using color %d\n", color);
1777ec3b29aSmrg      fflush(stdout);
1787ec3b29aSmrg      break;
17932001f49Smrg   case 'l':
18032001f49Smrg   case 'L':
18132001f49Smrg      LogicOp = GL_TRUE;
18232001f49Smrg      break;
18332001f49Smrg   case 27:
18432001f49Smrg      glutDestroyWindow(Win);
18532001f49Smrg      exit(0);
18632001f49Smrg      break;
18732001f49Smrg   }
18832001f49Smrg   RedrawBackground = GL_TRUE;
18932001f49Smrg   glutPostRedisplay();
19032001f49Smrg}
19132001f49Smrg
19232001f49Smrg
19332001f49Smrgstatic void
19432001f49SmrgSpecialKey(int key, int x, int y)
19532001f49Smrg{
19632001f49Smrg   (void) x;
19732001f49Smrg   (void) y;
19832001f49Smrg   switch (key) {
19932001f49Smrg   case GLUT_KEY_UP:
20032001f49Smrg      break;
20132001f49Smrg   case GLUT_KEY_DOWN:
20232001f49Smrg      break;
20332001f49Smrg   case GLUT_KEY_LEFT:
20432001f49Smrg      break;
20532001f49Smrg   case GLUT_KEY_RIGHT:
20632001f49Smrg      break;
20732001f49Smrg   }
20832001f49Smrg   glutPostRedisplay();
20932001f49Smrg}
21032001f49Smrg
21132001f49Smrg
21232001f49Smrgstatic void
21332001f49SmrgMouseMotion(int x, int y)
21432001f49Smrg{
21532001f49Smrg   if (ButtonDown) {
21632001f49Smrg      NewRect.x1 = x;
21732001f49Smrg      NewRect.y1 = y;
21832001f49Smrg      glutPostRedisplay();
21932001f49Smrg   }
22032001f49Smrg}
22132001f49Smrg
22232001f49Smrg
22332001f49Smrgstatic void
22432001f49SmrgMouseButton(int button, int state, int x, int y)
22532001f49Smrg{
22632001f49Smrg  if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
22732001f49Smrg     ButtonDown = GL_TRUE;
22832001f49Smrg     RedrawBackground = GL_TRUE;
22932001f49Smrg     NewRect.x0 = NewRect.x1 = x;
23032001f49Smrg     NewRect.y0 = NewRect.y1 = y;
23132001f49Smrg     OldRect = NewRect;
23232001f49Smrg  }
23332001f49Smrg  else if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) {
23432001f49Smrg     ButtonDown = GL_FALSE;
23532001f49Smrg  }
23632001f49Smrg  glutPostRedisplay();
23732001f49Smrg}
23832001f49Smrg
23932001f49Smrg
24032001f49Smrgstatic void
24132001f49SmrgInit(void)
24232001f49Smrg{
24332001f49Smrg   Image = LoadRGBImage(IMAGE_FILE, &ImgWidth, &ImgHeight, &ImgFormat);
24432001f49Smrg   if (!Image) {
24532001f49Smrg      printf("Couldn't read %s\n", IMAGE_FILE);
24632001f49Smrg      exit(0);
24732001f49Smrg   }
24832001f49Smrg
24932001f49Smrg   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
25032001f49Smrg   glPixelStorei(GL_PACK_ALIGNMENT, 1);
2517ec3b29aSmrg   glLineWidth(3);
25232001f49Smrg}
25332001f49Smrg
25432001f49Smrg
25532001f49Smrgint
25632001f49Smrgmain(int argc, char *argv[])
25732001f49Smrg{
25832001f49Smrg   glutInit(&argc, argv);
25932001f49Smrg   glutInitWindowSize(Width, Height);
26032001f49Smrg   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
26132001f49Smrg   Win = glutCreateWindow(argv[0]);
26232001f49Smrg   glewInit();
26332001f49Smrg   glutReshapeFunc(Reshape);
26432001f49Smrg   glutKeyboardFunc(Key);
26532001f49Smrg   glutSpecialFunc(SpecialKey);
26632001f49Smrg   glutMotionFunc(MouseMotion);
26732001f49Smrg   glutMouseFunc(MouseButton);
26832001f49Smrg   glutDisplayFunc(Draw);
26932001f49Smrg   Init();
27032001f49Smrg   glutPostRedisplay();
27132001f49Smrg   glutMainLoop();
27232001f49Smrg   return 0;
27332001f49Smrg}
274