132001f49Smrg/*
232001f49Smrg** blendxor.c - Demonstrates the use of the blend_logic_op
332001f49Smrg**    extension to draw hilights.  Using XOR to draw the same
432001f49Smrg**    image twice restores the background to its original value.
532001f49Smrg*/
632001f49Smrg
732001f49Smrg#include <stdio.h>
832001f49Smrg#include <string.h>
932001f49Smrg#ifndef _WIN32
1032001f49Smrg#include <unistd.h>
1132001f49Smrg#endif
1232001f49Smrg#include <stdlib.h>
1332001f49Smrg#include <GL/glew.h>
1432001f49Smrg#include "glut_wrap.h"
1532001f49Smrg
1632001f49Smrg
1732001f49SmrgGLenum doubleBuffer;
1832001f49Smrgint dithering = 0;
1932001f49Smrgint use11ops = 0;
2032001f49Smrgint supportlogops = 0;
2132001f49SmrgGLint windW, windH;
2232001f49Smrg
2332001f49Smrgstatic void Init(void)
2432001f49Smrg{
2532001f49Smrg    glDisable(GL_DITHER);
2632001f49Smrg    glShadeModel(GL_FLAT);
2732001f49Smrg}
2832001f49Smrg
2932001f49Smrgstatic void Reshape(int width, int height)
3032001f49Smrg{
3132001f49Smrg
3232001f49Smrg    windW = (GLint)width;
3332001f49Smrg    windH = (GLint)height;
3432001f49Smrg
3532001f49Smrg    glViewport(0, 0, (GLint)width, (GLint)height);
3632001f49Smrg
3732001f49Smrg    glMatrixMode(GL_PROJECTION);
3832001f49Smrg    glLoadIdentity();
3932001f49Smrg    gluOrtho2D(0, 400, 0, 400);
4032001f49Smrg    glMatrixMode(GL_MODELVIEW);
4132001f49Smrg}
4232001f49Smrg
4332001f49Smrgstatic void Key(unsigned char key, int x, int y)
4432001f49Smrg{
4532001f49Smrg
4632001f49Smrg    switch (key) {
4732001f49Smrg      case 27:
4832001f49Smrg	exit(1);
4932001f49Smrg      case 'd':
5032001f49Smrg	dithering = !dithering;
5132001f49Smrg	break;
5232001f49Smrg      case 'l':
5332001f49Smrg        if (supportlogops == 3)
5432001f49Smrg           use11ops = (!use11ops);
5532001f49Smrg        if (use11ops)
5632001f49Smrg           printf("Using GL 1.1 color logic ops.\n");
5732001f49Smrg        else printf("Using GL_EXT_blend_logic_op.\n");
5832001f49Smrg        break;
5932001f49Smrg      default:
6032001f49Smrg	return;
6132001f49Smrg    }
6232001f49Smrg
6332001f49Smrg    glutPostRedisplay();
6432001f49Smrg}
6532001f49Smrg
6632001f49Smrgstatic void Draw(void)
6732001f49Smrg{
6832001f49Smrg    int i;
6932001f49Smrg
7032001f49Smrg    glDisable(GL_BLEND);
7132001f49Smrg    if (supportlogops & 2)
7232001f49Smrg       glDisable(GL_COLOR_LOGIC_OP);
7332001f49Smrg
7432001f49Smrg    (dithering) ? glEnable(GL_DITHER) : glDisable(GL_DITHER);
7532001f49Smrg
7632001f49Smrg    glClearColor(0.5, 0.6, 0.1, 1.0);
7732001f49Smrg    glClear(GL_COLOR_BUFFER_BIT);
7832001f49Smrg
7932001f49Smrg    /* Draw background prims */
8032001f49Smrg    glColor3f(0.1, 0.1, 1.0);
8132001f49Smrg    glBegin(GL_TRIANGLES);
8232001f49Smrg        glVertex2i(5, 5);
8332001f49Smrg        glVertex2i(130, 50);
8432001f49Smrg        glVertex2i(100,  300);
8532001f49Smrg    glEnd();
8632001f49Smrg    glColor3f(0.5, 0.2, 0.9);
8732001f49Smrg    glBegin(GL_TRIANGLES);
8832001f49Smrg        glVertex2i(200, 100);
8932001f49Smrg        glVertex2i(330, 50);
9032001f49Smrg        glVertex2i(340,  400);
9132001f49Smrg    glEnd();
9232001f49Smrg
9332001f49Smrg    glEnable(GL_BLEND);
9432001f49Smrg    if (!use11ops)
9532001f49Smrg       glBlendEquationEXT(GL_LOGIC_OP);
9632001f49Smrg    else
9732001f49Smrg       glEnable(GL_COLOR_LOGIC_OP);
9832001f49Smrg    glLogicOp(GL_XOR);
9932001f49Smrg
10032001f49Smrg    /* Draw a set of rectangles across the window */
10132001f49Smrg    glColor3f(0.9, 0.2, 0.8);
10232001f49Smrg    for(i = 0; i < 400; i+=60) {
10332001f49Smrg        glBegin(GL_POLYGON);
10432001f49Smrg            glVertex2i(i, 100);
10532001f49Smrg            glVertex2i(i+50, 100);
10632001f49Smrg            glVertex2i(i+50, 200);
10732001f49Smrg            glVertex2i(i, 200);
10832001f49Smrg        glEnd();
10932001f49Smrg    }
11032001f49Smrg    glFlush();   /* Added by Brian Paul */
11132001f49Smrg#ifndef _WIN32
11232001f49Smrg    sleep(2);
11332001f49Smrg#endif
11432001f49Smrg
11532001f49Smrg    /* Redraw  the rectangles, which should erase them */
11632001f49Smrg    for(i = 0; i < 400; i+=60) {
11732001f49Smrg        glBegin(GL_POLYGON);
11832001f49Smrg            glVertex2i(i, 100);
11932001f49Smrg            glVertex2i(i+50, 100);
12032001f49Smrg            glVertex2i(i+50, 200);
12132001f49Smrg            glVertex2i(i, 200);
12232001f49Smrg        glEnd();
12332001f49Smrg    }
12432001f49Smrg    glFlush();
12532001f49Smrg
12632001f49Smrg
12732001f49Smrg    if (doubleBuffer) {
12832001f49Smrg	glutSwapBuffers();
12932001f49Smrg    }
13032001f49Smrg}
13132001f49Smrg
13232001f49Smrgstatic GLenum Args(int argc, char **argv)
13332001f49Smrg{
13432001f49Smrg    GLint i;
13532001f49Smrg
13632001f49Smrg    doubleBuffer = GL_FALSE;
13732001f49Smrg
13832001f49Smrg    for (i = 1; i < argc; i++) {
13932001f49Smrg	if (strcmp(argv[i], "-sb") == 0) {
14032001f49Smrg	    doubleBuffer = GL_FALSE;
14132001f49Smrg	} else if (strcmp(argv[i], "-db") == 0) {
14232001f49Smrg	    doubleBuffer = GL_TRUE;
14332001f49Smrg	} else {
14432001f49Smrg	    printf("%s (Bad option).\n", argv[i]);
14532001f49Smrg	    return GL_FALSE;
14632001f49Smrg	}
14732001f49Smrg    }
14832001f49Smrg    return GL_TRUE;
14932001f49Smrg}
15032001f49Smrg
15132001f49Smrgint main(int argc, char **argv)
15232001f49Smrg{
15332001f49Smrg    GLenum type;
15432001f49Smrg    char *s;
15532001f49Smrg    char *extName = "GL_EXT_blend_logic_op";
15632001f49Smrg    char *version;
15732001f49Smrg
15832001f49Smrg    glutInit(&argc, argv);
15932001f49Smrg
16032001f49Smrg    if (Args(argc, argv) == GL_FALSE) {
16132001f49Smrg	exit(1);
16232001f49Smrg    }
16332001f49Smrg
16432001f49Smrg    glutInitWindowPosition(0, 0); glutInitWindowSize( 400, 400);
16532001f49Smrg
16632001f49Smrg    type = GLUT_RGB;
16732001f49Smrg    type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
16832001f49Smrg    glutInitDisplayMode(type);
16932001f49Smrg
17032001f49Smrg    if (glutCreateWindow("Blend XOR") == GL_FALSE) {
17132001f49Smrg	exit(1);
17232001f49Smrg    }
17332001f49Smrg
17432001f49Smrg    glewInit();
17532001f49Smrg
17632001f49Smrg    /* Make sure blend_logic_op extension is there. */
17732001f49Smrg    s = (char *) glGetString(GL_EXTENSIONS);
17832001f49Smrg    version = (char*) glGetString(GL_VERSION);
17932001f49Smrg    if (!s)
18032001f49Smrg	exit(1);
18132001f49Smrg    if (strstr(s,extName)) {
18232001f49Smrg	supportlogops = 1;
18332001f49Smrg        use11ops = 0;
18432001f49Smrg        printf("blend_logic_op extension available.\n");
18532001f49Smrg    }
18632001f49Smrg    if (strncmp(version,"1.1",3)>=0) {
18732001f49Smrg    	supportlogops += 2;
18832001f49Smrg        use11ops = 1;
18932001f49Smrg	printf("1.1 color logic ops available.\n");
19032001f49Smrg    }
19132001f49Smrg    if (supportlogops == 0) {
19232001f49Smrg    	printf("Blend_logic_op extension and GL 1.1 not present.\n");
19332001f49Smrg	exit(1);
19432001f49Smrg    }
19532001f49Smrg
19632001f49Smrg    Init();
19732001f49Smrg
19832001f49Smrg    glutReshapeFunc(Reshape);
19932001f49Smrg    glutKeyboardFunc(Key);
20032001f49Smrg    glutDisplayFunc(Draw);
20132001f49Smrg    glutMainLoop();
20232001f49Smrg	return 0;
20332001f49Smrg}
204