Note: 3 texture environment functions (modulate, decal and blend) were
introduces with OpenGL 1.0.  GL 1.1 and 1.3 added the replace and add
functions, respectively.  As this test tests all 5 functions it is classified
as OpenGL 1.3.
---
 tests/all.py                        |   1 +
 tests/spec/gl-1.3/CMakeLists.gl.txt |   1 +
 tests/spec/gl-1.3/texture-env.c     | 526 ++++++++++++++++++++++++++++++++++++
 3 files changed, 528 insertions(+)
 create mode 100644 tests/spec/gl-1.3/texture-env.c

diff --git a/tests/all.py b/tests/all.py
index 3fd1153..3142ad2 100644
--- a/tests/all.py
+++ b/tests/all.py
@@ -1037,6 +1037,7 @@ with profile.test_list.group_manager(
         grouptools.join('spec', '!opengl 1.3')) as g:
     g(['texunits'])
     g(['tex-border-1'])
+    g(['gl-1.3-texture-env'])
     g(['tex3d-depth1'])
 
 with profile.test_list.group_manager(
diff --git a/tests/spec/gl-1.3/CMakeLists.gl.txt 
b/tests/spec/gl-1.3/CMakeLists.gl.txt
index 607d2c1..8eaa94d 100644
--- a/tests/spec/gl-1.3/CMakeLists.gl.txt
+++ b/tests/spec/gl-1.3/CMakeLists.gl.txt
@@ -9,5 +9,6 @@ link_libraries (
 )
 
 piglit_add_executable (gl-1.3-alpha_to_coverage_nop alpha_to_coverage_nop.c)
+piglit_add_executable (gl-1.3-texture-env texture-env.c)
 
 # vim: ft=cmake:
diff --git a/tests/spec/gl-1.3/texture-env.c b/tests/spec/gl-1.3/texture-env.c
new file mode 100644
index 0000000..7b43507
--- /dev/null
+++ b/tests/spec/gl-1.3/texture-env.c
@@ -0,0 +1,526 @@
+/*
+ * Copyright (C) 1999  Allen Akin   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL ALLEN AKIN BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/**
+ * @file tex-env.c:  Test the basic texture env modes
+ * Author: Brian Paul (bri...@valinux.com)  April 2001
+ *
+ * Test procedure:
+ *   Setup a texture with 81 columns of unique RGBA colors, 3 texels each.
+ *   Draw a 81 uniquely-colored flat-shaded quads as wide horizontal bands,
+ *   with the above texture.  This makes a matrix of 81*81 colored squares
+ *   for which we test that the current texture environment mode and texture
+ *   format produced the correct color.
+ *   Finally, we blend over a gray background in order to verify that the
+ *   post-texture alpha value is correct.
+ */
+
+#include "piglit-util-gl.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+       config.supports_gl_compat_version = 13;
+       config.window_visual = PIGLIT_GL_VISUAL_RGBA;
+       config.khr_no_error_support = PIGLIT_NO_ERRORS;
+       config.window_width = 256;
+       config.window_height = 256;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+#define BLEND_WITH_BACKGROUND 1
+
+#define COLORS (3 * 3 * 3 * 3)
+
+static float colors[COLORS][4];
+
+static float bg_color[4] = {0.5, 0.5, 0.5, 0.5};
+
+static const GLenum format_enums[] = {
+       GL_ALPHA,
+       GL_LUMINANCE,
+       GL_LUMINANCE_ALPHA,
+       GL_INTENSITY,
+       GL_RGB,
+       GL_RGBA
+};
+
+static const GLenum env_mode_enums[] = {
+       GL_REPLACE,
+       GL_MODULATE,
+       GL_DECAL,
+       GL_BLEND,
+       GL_ADD
+};
+
+/* Compute expected texenv result given the texture env mode, the texture
+ * base format, texture color, fragment color, and texture env color.
+ * This also blends the result with the background color if that option
+ * is enabled (see above). */
+static void
+compute_expected_color(GLenum env_mode, GLenum tex_format,
+                      const float tex_color[4], const float frag_color[4],
+                      const float env_color[4], float result[4])
+{
+       switch (env_mode) {
+       case GL_REPLACE:
+               switch (tex_format) {
+               case GL_ALPHA:
+                       result[0] = frag_color[0];
+                       result[1] = frag_color[1];
+                       result[2] = frag_color[2];
+                       result[3] = tex_color[3]; /* alpha */
+                       break;
+               case GL_LUMINANCE:
+                       result[0] = tex_color[0]; /* lum */
+                       result[1] = tex_color[0];
+                       result[2] = tex_color[0];
+                       result[3] = frag_color[3];
+                       break;
+               case GL_LUMINANCE_ALPHA:
+                       result[0] = tex_color[0]; /* lum */
+                       result[1] = tex_color[0];
+                       result[2] = tex_color[0];
+                       result[3] = tex_color[3]; /* alpha */
+                       break;
+               case GL_INTENSITY:
+                       result[0] = tex_color[0]; /* intensity */
+                       result[1] = tex_color[0];
+                       result[2] = tex_color[0];
+                       result[3] = tex_color[0];
+                       break;
+               case GL_RGB:
+                       result[0] = tex_color[0]; /* r */
+                       result[1] = tex_color[1]; /* g */
+                       result[2] = tex_color[2]; /* b */
+                       result[3] = frag_color[3];
+                       break;
+               case GL_RGBA:
+                       result[0] = tex_color[0]; /* r */
+                       result[1] = tex_color[1]; /* g */
+                       result[2] = tex_color[2]; /* b */
+                       result[3] = tex_color[3]; /* a */
+                       break;
+               default:
+                       abort(); /* implementation error */
+               }
+               break;
+       case GL_MODULATE:
+               switch (tex_format) {
+               case GL_ALPHA:
+                       result[0] = frag_color[0];
+                       result[1] = frag_color[1];
+                       result[2] = frag_color[2];
+                       result[3] = frag_color[3] * tex_color[3];
+                       break;
+               case GL_LUMINANCE:
+                       result[0] = frag_color[0] * tex_color[0];
+                       result[1] = frag_color[1] * tex_color[0];
+                       result[2] = frag_color[2] * tex_color[0];
+                       result[3] = frag_color[3];
+                       break;
+               case GL_LUMINANCE_ALPHA:
+                       result[0] = frag_color[0] * tex_color[0];
+                       result[1] = frag_color[1] * tex_color[0];
+                       result[2] = frag_color[2] * tex_color[0];
+                       result[3] = frag_color[3] * tex_color[3];
+                       break;
+               case GL_INTENSITY:
+                       result[0] = frag_color[0] * tex_color[0];
+                       result[1] = frag_color[1] * tex_color[0];
+                       result[2] = frag_color[2] * tex_color[0];
+                       result[3] = frag_color[3] * tex_color[0];
+                       break;
+               case GL_RGB:
+                       result[0] = frag_color[0] * tex_color[0];
+                       result[1] = frag_color[1] * tex_color[1];
+                       result[2] = frag_color[2] * tex_color[2];
+                       result[3] = frag_color[3];
+                       break;
+               case GL_RGBA:
+                       result[0] = frag_color[0] * tex_color[0];
+                       result[1] = frag_color[1] * tex_color[1];
+                       result[2] = frag_color[2] * tex_color[2];
+                       result[3] = frag_color[3] * tex_color[3];
+                       break;
+               default:
+                       abort(); /* implementation error */
+               }
+               break;
+       case GL_DECAL:
+               switch (tex_format) {
+               case GL_ALPHA:
+                       result[0] = 0; /* undefined */
+                       result[1] = 0;
+                       result[2] = 0;
+                       result[3] = 0;
+                       break;
+               case GL_LUMINANCE:
+                       result[0] = 0; /* undefined */
+                       result[1] = 0;
+                       result[2] = 0;
+                       result[3] = 0;
+                       break;
+               case GL_LUMINANCE_ALPHA:
+                       result[0] = 0; /* undefined */
+                       result[1] = 0;
+                       result[2] = 0;
+                       result[3] = 0;
+                       break;
+               case GL_INTENSITY:
+                       result[0] = 0; /* undefined */
+                       result[1] = 0;
+                       result[2] = 0;
+                       result[3] = 0;
+                       break;
+               case GL_RGB:
+                       result[0] = tex_color[0];
+                       result[1] = tex_color[1];
+                       result[2] = tex_color[2];
+                       result[3] = frag_color[3];
+                       break;
+               case GL_RGBA: {
+                       const float a = tex_color[3];
+                       const float oma = 1.0 - a;
+                       result[0] = frag_color[0] * oma + tex_color[0] * a;
+                       result[1] = frag_color[1] * oma + tex_color[1] * a;
+                       result[2] = frag_color[2] * oma + tex_color[2] * a;
+                       result[3] = frag_color[3];
+               } break;
+               default:
+                       abort(); /* implementation error */
+               }
+               break;
+       case GL_BLEND:
+               switch (tex_format) {
+               case GL_ALPHA:
+                       result[0] = frag_color[0];
+                       result[1] = frag_color[1];
+                       result[2] = frag_color[2];
+                       result[3] = frag_color[3] * tex_color[3];
+                       break;
+               case GL_LUMINANCE: {
+                       const float l = tex_color[0];
+                       const float oml = 1.0 - l;
+                       result[0] = frag_color[0] * oml + env_color[0] * l;
+                       result[1] = frag_color[1] * oml + env_color[1] * l;
+                       result[2] = frag_color[2] * oml + env_color[2] * l;
+                       result[3] = frag_color[3];
+               } break;
+               case GL_LUMINANCE_ALPHA: {
+                       const float l = tex_color[0];
+                       const float oml = 1.0 - l;
+                       result[0] = frag_color[0] * oml + env_color[0] * l;
+                       result[1] = frag_color[1] * oml + env_color[1] * l;
+                       result[2] = frag_color[2] * oml + env_color[2] * l;
+                       result[3] = frag_color[3] * tex_color[3];
+               } break;
+               case GL_INTENSITY: {
+                       const float i = tex_color[0];
+                       const float omi = 1.0 - i;
+                       result[0] = frag_color[0] * omi + env_color[0] * i;
+                       result[1] = frag_color[1] * omi + env_color[1] * i;
+                       result[2] = frag_color[2] * omi + env_color[2] * i;
+                       result[3] = frag_color[3] * omi + env_color[3] * i;
+               } break;
+               case GL_RGB: {
+                       const float r = tex_color[0];
+                       const float omr = 1.0 - r;
+                       const float g = tex_color[1];
+                       const float omg = 1.0 - g;
+                       const float b = tex_color[2];
+                       const float omb = 1.0 - b;
+                       result[0] = frag_color[0] * omr + env_color[0] * r;
+                       result[1] = frag_color[1] * omg + env_color[1] * g;
+                       result[2] = frag_color[2] * omb + env_color[2] * b;
+                       result[3] = frag_color[3];
+               } break;
+               case GL_RGBA: {
+                       const float r = tex_color[0];
+                       const float omr = 1.0 - r;
+                       const float g = tex_color[1];
+                       const float omg = 1.0 - g;
+                       const float b = tex_color[2];
+                       const float omb = 1.0 - b;
+                       result[0] = frag_color[0] * omr + env_color[0] * r;
+                       result[1] = frag_color[1] * omg + env_color[1] * g;
+                       result[2] = frag_color[2] * omb + env_color[2] * b;
+                       result[3] = frag_color[3] * tex_color[3];
+               } break;
+               default:
+                       abort(); /* implementation error */
+               }
+               break;
+       case GL_ADD:
+               switch (tex_format) {
+               case GL_ALPHA:
+                       result[0] = frag_color[0];
+                       result[1] = frag_color[1];
+                       result[2] = frag_color[2];
+                       result[3] = frag_color[3] * tex_color[3];
+                       break;
+               case GL_LUMINANCE:
+                       result[0] = frag_color[0] + tex_color[0];
+                       result[1] = frag_color[1] + tex_color[0];
+                       result[2] = frag_color[2] + tex_color[0];
+                       result[3] = frag_color[3];
+                       break;
+               case GL_LUMINANCE_ALPHA:
+                       result[0] = frag_color[0] + tex_color[0];
+                       result[1] = frag_color[1] + tex_color[0];
+                       result[2] = frag_color[2] + tex_color[0];
+                       result[3] = frag_color[3] * tex_color[3];
+                       break;
+               case GL_INTENSITY:
+                       result[0] = frag_color[0] + tex_color[0];
+                       result[1] = frag_color[1] + tex_color[0];
+                       result[2] = frag_color[2] + tex_color[0];
+                       result[3] = frag_color[3] + tex_color[0];
+                       break;
+               case GL_RGB:
+                       result[0] = frag_color[0] + tex_color[0];
+                       result[1] = frag_color[1] + tex_color[1];
+                       result[2] = frag_color[2] + tex_color[2];
+                       result[3] = frag_color[3];
+                       break;
+               case GL_RGBA:
+                       result[0] = frag_color[0] + tex_color[0];
+                       result[1] = frag_color[1] + tex_color[1];
+                       result[2] = frag_color[2] + tex_color[2];
+                       result[3] = frag_color[3] * tex_color[3];
+                       break;
+               default:
+                       abort(); /* implementation error */
+               }
+               /* clamping */
+               if (result[0] > 1.0)
+                       result[0] = 1.0;
+               if (result[1] > 1.0)
+                       result[1] = 1.0;
+               if (result[2] > 1.0)
+                       result[2] = 1.0;
+               if (result[3] > 1.0)
+                       result[3] = 1.0;
+               break;
+       default:
+               abort(); /* implementation error */
+       }
+
+#if BLEND_WITH_BACKGROUND
+       /* now blend result over a gray background */
+       const float alpha = result[3];
+       const float om_alpha = 1.0 - alpha;
+       result[0] = result[0] * alpha + bg_color[0] * om_alpha;
+       result[1] = result[1] * alpha + bg_color[1] * om_alpha;
+       result[2] = result[2] * alpha + bg_color[2] * om_alpha;
+       result[3] = result[3] * alpha + bg_color[3] * om_alpha;
+#endif
+}
+
+/* Make a texture in which the colors vary along the length
+ * according to the colors[] array.  For example, we use
+ * 243 columns of the texture to store 81 colors, 3 texels each. */
+static void
+make_tex_image(GLenum base_format, int num_colors, const float colors[][4])
+{
+#define WIDTH 256
+#define HEIGHT 4
+       static float img[WIDTH * HEIGHT][4];
+
+       assert(num_colors == 81);
+
+       for (int i = 0; i < HEIGHT; i++) {
+               for (int j = 0; j < WIDTH; j++) {
+                       int c = j / 3;
+                       if (c >= num_colors) {
+                               img[i * WIDTH + j][0] = 0.0;
+                               img[i * WIDTH + j][1] = 0.0;
+                               img[i * WIDTH + j][2] = 0.0;
+                               img[i * WIDTH + j][3] = 0.0;
+                       } else {
+                               img[i * WIDTH + j][0] = colors[c][0];
+                               img[i * WIDTH + j][1] = colors[c][1];
+                               img[i * WIDTH + j][2] = colors[c][2];
+                               img[i * WIDTH + j][3] = colors[c][3];
+                       }
+               }
+       }
+
+       glTexImage2D(GL_TEXTURE_2D, 0, base_format, WIDTH, HEIGHT, 0, GL_RGBA,
+                    GL_FLOAT, (void *)img);
+}
+
+/* Do num_colors * num_colors tests in one batch.
+ * Setup a texture in which the colors vary by column.
+ * Draw a quadstrip in which we draw horizontal bands of colors.
+ * Drawing the textured quadstrips will fill the window with
+ * num_colors * num_colors test squares.
+ * Verify that they're all correct.
+ * Return:  true = pass, false = fail */
+static bool
+matrix_test(GLenum env_mode, GLenum tex_format, int num_colors,
+           const float colors[][4], const float env_color[4])
+{
+       const char *format_name = piglit_get_gl_enum_name(tex_format);
+       const char *env_name = piglit_get_gl_enum_name(env_mode);
+
+       if (env_mode == GL_DECAL &&
+           (tex_format != GL_RGB && tex_format != GL_RGBA)) {
+               /* undefined mode */
+               return true;
+       }
+
+       glClear(GL_COLOR_BUFFER_BIT);
+
+       /* The texture colors are the columns */
+       make_tex_image(tex_format, num_colors, colors);
+
+       glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, env_mode);
+       glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, env_color);
+
+       /* The fragment colors are the rows */
+       float W = num_colors * 3;
+       float S = (float)(num_colors * 3) / (float)256;
+       glBegin(GL_QUAD_STRIP);
+       glTexCoord2f(0, 0);  glVertex2f(0, 0);
+       glTexCoord2f(S, 0);  glVertex2f(W, 0);
+       for (int i = 0; i < num_colors; i++) {
+               glColor4fv(colors[i]);
+               float y = i * 3 + 3;
+               float t = y / (num_colors * 3);
+               glTexCoord2f(0, t);  glVertex2f(0, y);
+               glTexCoord2f(S, t);  glVertex2f(W, y);
+       }
+       glEnd();
+
+       /* Check results */
+       for (int row = 0; row < num_colors; row++) {
+               for (int col = 0; col < num_colors; col++) {
+
+                       /* compute expected */
+                       float expected[4];
+                       compute_expected_color(env_mode, tex_format,
+                                              colors[col], colors[row],
+                                              env_color, expected);
+
+                       /* fetch actual pixel */
+                       int x = col * 3 + 1;
+                       int y = row * 3 + 1;
+
+                       /* compare */
+                       if (!piglit_probe_pixel_rgba(x, y, expected)) {
+                               /* Report the error */
+                               printf("GL_TEXTURE_ENV_MODE = %s\n"
+                                      "Texture Format = %s\n"
+                                      "Fragment Color = (%f, %f, %f, %f)\n"
+                                      "Texture Color = (%f, %f, %f, %f)\n"
+                                      "Tex Env Color = (%f, %f, %f, %f)\n",
+                                      env_name, format_name,
+                                      colors[row][0], colors[row][1],
+                                      colors[row][2], colors[row][3],
+                                      colors[col][0], colors[col][1],
+                                      colors[col][2], colors[col][3],
+                                      env_color[0], env_color[1],
+                                      env_color[2], env_color[3]);
+#if BLEND_WITH_BACKGROUND
+                               printf("Blend over = (%f, %f, %f, %f)\n",
+                                      bg_color[0], bg_color[1],
+                                      bg_color[2], bg_color[3]);
+#endif
+                               return false;
+                       }
+               }
+       }
+       return true;
+}
+
+enum piglit_result
+piglit_display(void)
+{
+       bool pass = true;
+
+       for (int fmt = 0; fmt < 6; fmt++) {
+               const GLenum format = format_enums[fmt];
+               for (int mode = 0; mode < 5; mode++) {
+                       const GLenum env_mode = env_mode_enums[mode];
+                       if (env_mode == GL_BLEND && format != GL_ALPHA) {
+                               /* also vary texenv color, every 5th is OK. */
+                               for (int i = 0; i < COLORS; i += 5) {
+                                       const float *env_color = colors[i];
+                                       if (!matrix_test(env_mode, format,
+                                                        COLORS, colors,
+                                                        env_color)) {
+                                               pass = false;
+                                               break;
+                                       }
+                               }
+                       } else {
+                               /* texenv color not significant */
+                               if (!matrix_test(env_mode, format, COLORS,
+                                                colors, colors[0])) {
+                                       pass = false;
+                               }
+                       }
+               }
+       }
+
+       return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+       GLuint texture;
+
+       /* colors[] is an array of all possible RGBA colors with component
+        * values of 0, 0.5, and 1.0 */
+       for (int i = 0; i < COLORS; i++) {
+               int r = i % 3;
+               int g = (i / 3) % 3;
+               int b = (i / 9) % 3;
+               int a = (i / 27) % 3;
+               colors[i][0] = (float)r / 2.0;
+               colors[i][1] = (float)g / 2.0;
+               colors[i][2] = (float)b / 2.0;
+               colors[i][3] = (float)a / 2.0;
+       }
+
+       glGenTextures(1, &texture);
+       glBindTexture(GL_TEXTURE_2D, texture);
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+       glEnable(GL_TEXTURE_2D);
+
+#if BLEND_WITH_BACKGROUND
+       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+       glEnable(GL_BLEND);
+#endif
+
+       glClearColor(bg_color[0], bg_color[1], bg_color[2], bg_color[3]);
+       glShadeModel(GL_FLAT);
+
+       piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
+}
-- 
2.7.4

_______________________________________________
Piglit mailing list
Piglit@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/piglit

Reply via email to