From f97792421ba3ea0af1f1976e5e267e88314885a2 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 19 Jan 2009 12:03:17 -0700 Subject: [PATCH] tests: test pseudo-XOR blend mode. GL_XOR logicop mode can be approximated with blending by computing 1 - dst. Here's a couple test programs for that. --- progs/tests/Makefile | 2 + progs/tests/blendxor.c | 196 +++++++++++++++++++++++++++++++ progs/tests/rubberband.c | 245 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 443 insertions(+) create mode 100644 progs/tests/blendxor.c create mode 100644 progs/tests/rubberband.c diff --git a/progs/tests/Makefile b/progs/tests/Makefile index 86b0cb537be..5f17f88d36c 100644 --- a/progs/tests/Makefile +++ b/progs/tests/Makefile @@ -26,6 +26,7 @@ SOURCES = \ arraytexture.c \ blendminmax.c \ blendsquare.c \ + blendxor.c \ bufferobj.c \ bug_3050.c \ bug_3101.c \ @@ -60,6 +61,7 @@ SOURCES = \ projtex.c \ random.c \ readrate.c \ + rubberband.c \ seccolor.c \ shader_api.c \ sharedtex.c \ diff --git a/progs/tests/blendxor.c b/progs/tests/blendxor.c new file mode 100644 index 00000000000..8961a827eab --- /dev/null +++ b/progs/tests/blendxor.c @@ -0,0 +1,196 @@ +/** + * Test XOR emulation with blending. + * + */ + +#define GL_GLEXT_PROTOTYPES +#include +#include +#include +#include +#include "readtex.c" + +#define IMAGE_FILE "../images/arch.rgb" + +static int ImgWidth, ImgHeight; +static GLenum ImgFormat; +static GLubyte *Image = NULL; + +static int Win; +static int Width = 600, Height = 600; + +struct rect +{ + int x0, y0, x1, y1; +}; + +static struct rect OldRect, NewRect; + +static GLboolean ButtonDown = GL_FALSE; +static GLboolean LogicOp = 0*GL_TRUE; + + +static const GLfloat red[4] = {1.0, 0.2, 0.2, 1.0}; +static const GLfloat green[4] = {0.2, 1.0, 0.2, 1.0}; +static const GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0}; + + +static void +PrintString(const char *s) +{ + while (*s) { + glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s); + s++; + } +} + + +static void +Draw(void) +{ + glClear(GL_COLOR_BUFFER_BIT); + + glWindowPos2i((Width - ImgWidth) / 2, (Height - ImgHeight) / 2); + glDrawPixels(ImgWidth, ImgHeight, ImgFormat, GL_UNSIGNED_BYTE, Image); + + /* + * Draw 2D XOR rects + */ + glColor3f(1, 1, 1); + + glWindowPos2i(100, Height - 20); + PrintString("XOR LogicOp:"); + glLogicOp(GL_XOR); + glEnable(GL_COLOR_LOGIC_OP); + glRecti(100, 30, 250, Height - 30); + glDisable(GL_COLOR_LOGIC_OP); + + glWindowPos2i(Width/2 + 10, Height - 20); + PrintString("Invert Blending:"); + glBlendFunc(GL_ONE, GL_ONE); + glBlendEquation(GL_FUNC_SUBTRACT); + glEnable(GL_BLEND); + glRecti(Width / 2, 30, Width / 2 + 150, Height - 30); + glDisable(GL_BLEND); + + glutSwapBuffers(); +} + + +static void +Reshape(int width, int height) +{ + Width = width; + Height = height; + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, Width, 0, Height, -1, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + + +static void +Key(unsigned char key, int x, int y) +{ + (void) x; + (void) y; + switch (key) { + case 'b': + case 'B': + LogicOp = GL_FALSE; + break; + case 'l': + case 'L': + LogicOp = GL_TRUE; + break; + case 27: + glutDestroyWindow(Win); + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void +SpecialKey(int key, int x, int y) +{ + (void) x; + (void) y; + switch (key) { + case GLUT_KEY_UP: + break; + case GLUT_KEY_DOWN: + break; + case GLUT_KEY_LEFT: + break; + case GLUT_KEY_RIGHT: + break; + } + glutPostRedisplay(); +} + + +static void +MouseMotion(int x, int y) +{ + if (ButtonDown) { + NewRect.x1 = x; + NewRect.y1 = y; + glutPostRedisplay(); + } +} + + +static void +MouseButton(int button, int state, int x, int y) +{ + if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { + ButtonDown = GL_TRUE; + NewRect.x0 = NewRect.x1 = x; + NewRect.y0 = NewRect.y1 = y; + OldRect = NewRect; + } + else if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) { + ButtonDown = GL_FALSE; + } +} + + +static void +Init(void) +{ + /* + * Load image and scale if needed. + */ + Image = LoadRGBImage(IMAGE_FILE, &ImgWidth, &ImgHeight, &ImgFormat); + if (!Image) { + printf("Couldn't read %s\n", IMAGE_FILE); + exit(0); + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glPixelStorei(GL_PACK_ALIGNMENT, 1); +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowSize(Width, Height); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); + Win = glutCreateWindow(argv[0]); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutSpecialFunc(SpecialKey); + glutMotionFunc(MouseMotion); + glutMouseFunc(MouseButton); + glutDisplayFunc(Draw); + Init(); + glutPostRedisplay(); + glutMainLoop(); + return 0; +} diff --git a/progs/tests/rubberband.c b/progs/tests/rubberband.c new file mode 100644 index 00000000000..a8e64bc0916 --- /dev/null +++ b/progs/tests/rubberband.c @@ -0,0 +1,245 @@ +/** + * Test rubber-band selection box w/ logicops and blend. + */ + +#define GL_GLEXT_PROTOTYPES +#include +#include +#include +#include +#include "readtex.c" + +#define IMAGE_FILE "../images/arch.rgb" + +static int ImgWidth, ImgHeight; +static GLenum ImgFormat; +static GLubyte *Image = NULL; + +static int Win; +static int Width = 512, Height = 512; + +struct rect +{ + int x0, y0, x1, y1; +}; + +static struct rect OldRect, NewRect; + +static GLboolean ButtonDown = GL_FALSE; +static GLboolean LogicOp = 0*GL_TRUE; + +static GLboolean RedrawBackground = GL_TRUE; + +static const GLfloat red[4] = {1.0, 0.2, 0.2, 1.0}; +static const GLfloat green[4] = {0.2, 1.0, 0.2, 1.0}; +static const GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0}; + + +/* + * Draw rubberband box in front buffer + */ +static void +DrawRect(const struct rect *r) +{ + glDrawBuffer(GL_FRONT); + + if (LogicOp) { + glLogicOp(GL_XOR); + glEnable(GL_COLOR_LOGIC_OP); + } + else { + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE); + glBlendEquation(GL_FUNC_SUBTRACT); + } + + glColor3f(1, 1, 1); + + glLineWidth(3.0); + + glBegin(GL_LINE_LOOP); + glVertex2i(r->x0, r->y0); + glVertex2i(r->x1, r->y0); + glVertex2i(r->x1, r->y1); + glVertex2i(r->x0, r->y1); + glEnd(); + + glDisable(GL_COLOR_LOGIC_OP); + glDisable(GL_BLEND); + + glDrawBuffer(GL_BACK); +} + + +static void +PrintString(const char *s) +{ + while (*s) { + glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s); + s++; + } +} + + +static void +DrawBackground(void) +{ + char s[100]; + + sprintf(s, "[L/B] %s mode. Use mouse to make selection box.", + LogicOp ? "LogicOp" : "Blend"); + + glClear(GL_COLOR_BUFFER_BIT); + + glWindowPos2i((Width - ImgWidth) / 2, (Height - ImgHeight) / 2); + glDrawPixels(ImgWidth, ImgHeight, ImgFormat, GL_UNSIGNED_BYTE, Image); + + glWindowPos2i(10, 10); + PrintString(s); + + glutSwapBuffers(); +} + + +static void +Draw(void) +{ + if (RedrawBackground) { + DrawBackground(); + } + + if (ButtonDown) { + if (!RedrawBackground) + DrawRect(&OldRect); /* erase old */ + + DrawRect(&NewRect); /* draw new */ + + OldRect = NewRect; + } + + RedrawBackground = GL_FALSE; +} + + +static void +Reshape(int width, int height) +{ + Width = width; + Height = height; + + glViewport(0, 0, width, height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, Width, Height, 0, -1, 1); /* Inverted Y! */ + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + RedrawBackground = GL_TRUE; +} + + +static void +Key(unsigned char key, int x, int y) +{ + (void) x; + (void) y; + switch (key) { + case 'b': + case 'B': + LogicOp = GL_FALSE; + break; + case 'l': + case 'L': + LogicOp = GL_TRUE; + break; + case 27: + glutDestroyWindow(Win); + exit(0); + break; + } + RedrawBackground = GL_TRUE; + glutPostRedisplay(); +} + + +static void +SpecialKey(int key, int x, int y) +{ + (void) x; + (void) y; + switch (key) { + case GLUT_KEY_UP: + break; + case GLUT_KEY_DOWN: + break; + case GLUT_KEY_LEFT: + break; + case GLUT_KEY_RIGHT: + break; + } + glutPostRedisplay(); +} + + +static void +MouseMotion(int x, int y) +{ + if (ButtonDown) { + NewRect.x1 = x; + NewRect.y1 = y; + glutPostRedisplay(); + } +} + + +static void +MouseButton(int button, int state, int x, int y) +{ + if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { + ButtonDown = GL_TRUE; + RedrawBackground = GL_TRUE; + NewRect.x0 = NewRect.x1 = x; + NewRect.y0 = NewRect.y1 = y; + OldRect = NewRect; + } + else if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) { + ButtonDown = GL_FALSE; + } + glutPostRedisplay(); +} + + +static void +Init(void) +{ + Image = LoadRGBImage(IMAGE_FILE, &ImgWidth, &ImgHeight, &ImgFormat); + if (!Image) { + printf("Couldn't read %s\n", IMAGE_FILE); + exit(0); + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glPixelStorei(GL_PACK_ALIGNMENT, 1); +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowSize(Width, Height); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); + Win = glutCreateWindow(argv[0]); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutSpecialFunc(SpecialKey); + glutMotionFunc(MouseMotion); + glutMouseFunc(MouseButton); + glutDisplayFunc(Draw); + Init(); + glutPostRedisplay(); + glutMainLoop(); + return 0; +} -- 2.30.2