Demos (master): shadow-sample: an old GLSL shadow sampler test

Brian Paul brianp at kemper.freedesktop.org
Sun Apr 10 16:01:19 PDT 2011


Module: Demos
Branch: master
Commit: 6c208659e5649cd90112392d2aeff468bcc0457a
URL:    http://cgit.freedesktop.org/mesa/demos/commit/?id=6c208659e5649cd90112392d2aeff468bcc0457a

Author: Brian Paul <brianp at vmware.com>
Date:   Sun Apr 10 16:57:06 2011 -0600

shadow-sample: an old GLSL shadow sampler test

---

 src/tests/CMakeLists.txt  |    1 +
 src/tests/Makefile.am     |    1 +
 src/tests/shadow-sample.c |  319 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 321 insertions(+), 0 deletions(-)

diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt
index 2d72ef3..fb20c04 100644
--- a/src/tests/CMakeLists.txt
+++ b/src/tests/CMakeLists.txt
@@ -99,6 +99,7 @@ set (targets
 	seccolor
 	shader_api
 	shader-interp
+	shadow-sample
 	stencilreaddraw
 	stencilwrap
 	step
diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am
index a57c800..0d7c411 100644
--- a/src/tests/Makefile.am
+++ b/src/tests/Makefile.am
@@ -125,6 +125,7 @@ noinst_PROGRAMS = \
 	seccolor \
 	shader_api \
 	shader-interp \
+	shadow-sample \
 	sharedtex \
 	stencilreaddraw \
 	stencilwrap \
diff --git a/src/tests/shadow-sample.c b/src/tests/shadow-sample.c
new file mode 100644
index 0000000..1d85ef1
--- /dev/null
+++ b/src/tests/shadow-sample.c
@@ -0,0 +1,319 @@
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <GL/glew.h>
+#include <GL/glut.h>
+
+#define windowSize 100
+GLfloat tolerance[5];
+struct ShaderProgram
+{
+   const char *name;
+   const char *fragShaderString;
+   GLfloat expectedColor[4];
+} Programs[] = {
+   {
+      "shadow2D(): 1", "uniform sampler2DShadow texZ; \n"
+         "void main() { \n"
+         "   vec3 coord = vec3(0.1, 0.1, 0.5); \n"
+         "   // shadow map value should be 0.25 \n"
+         "   gl_FragColor = shadow2D(texZ, coord) + vec4(0.25); \n"
+         "   // 0.5 <= 0.25 ? color = 1 : 0\n" "} \n", {
+   0.25, 0.25, 0.25, 1.0},}, {
+      "shadow2D(): 2", "uniform sampler2DShadow texZ; \n"
+         "void main() { \n"
+         "   vec3 coord = vec3(0.1, 0.1, 0.2); \n"
+         "   // shadow map value should be 0.25 \n"
+         "   gl_FragColor = shadow2D(texZ, coord); \n"
+         "   // 0.2 <= 0.25 ? color = 1 : 0\n" "} \n", {
+   1.0, 1.0, 1.0, 1.0},}, {
+      "shadow2D(): 3", "uniform sampler2DShadow texZ; \n"
+         "void main() { \n"
+         "   vec3 coord = vec3(0.9, 0.9, 0.95); \n"
+         "   // shadow map value should be 0.75 \n"
+         "   gl_FragColor = shadow2D(texZ, coord) + vec4(0.25); \n"
+         "   // 0.95 <= 0.75 ? color = 1 : 0\n" "} \n", {
+   0.25, 0.25, 0.25, 1.0},}, {
+      "shadow2D(): 4", "uniform sampler2DShadow texZ; \n"
+         "void main() { \n"
+         "   vec3 coord = vec3(0.9, 0.9, 0.65); \n"
+         "   // shadow map value should be 0.75 \n"
+         "   gl_FragColor = shadow2D(texZ, coord); \n"
+         "   // 0.65 <= 0.75 ? color = 1 : 0\n" "} \n", {
+   1.0, 1.0, 1.0, 1.0}}, {
+      NULL, NULL, {
+0, 0, 0, 0}}};
+
+static void
+setupTextures(void)
+{
+   GLfloat teximageZ[16][16];
+   GLint i, j;
+   GLuint objZ;
+   glGenTextures(1, &objZ);
+
+   /* 2D GL_DEPTH_COMPONENT texture (for shadow sampler tests) */
+   for (i = 0; i < 16; i++) {
+      for (j = 0; j < 16; j++) {
+         if (j < 8)
+            teximageZ[i][j] = 0.25;
+
+         else
+            teximageZ[i][j] = 0.75;
+      }
+   }
+   glBindTexture(GL_TEXTURE_2D, objZ);
+   glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 16, 16, 0,
+                GL_DEPTH_COMPONENT, GL_FLOAT, teximageZ);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB,
+                   GL_COMPARE_R_TO_TEXTURE_ARB);
+}
+
+static void
+Init(void)
+{
+
+   /* check GLSL version */
+   GLenum err;
+   int bufferBits[5];
+   const char *glslVersion =
+      (const char *) glGetString(GL_SHADING_LANGUAGE_VERSION);
+   if (!glslVersion || glslVersion[0] != '1') {
+      fprintf(stderr, "GLSL 1.x not supported\n");
+      return;
+   }
+   setupTextures();
+   err = glGetError();
+   assert(!err);                /* should be OK */
+
+   /* setup vertex transform (we'll draw a quad in middle of window) */
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   glOrtho(-4.0, 4.0, -4.0, 4.0, 0.0, 1.0);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+   glDrawBuffer(GL_FRONT);
+   glReadBuffer(GL_FRONT);
+
+   /* compute error tolerances (may need fine-tuning) */
+   glGetIntegerv(GL_RED_BITS, &bufferBits[0]);
+   glGetIntegerv(GL_GREEN_BITS, &bufferBits[1]);
+   glGetIntegerv(GL_BLUE_BITS, &bufferBits[2]);
+   glGetIntegerv(GL_ALPHA_BITS, &bufferBits[3]);
+   glGetIntegerv(GL_DEPTH_BITS, &bufferBits[4]);
+   tolerance[0] = 2.0 / (1 << bufferBits[0]);
+   tolerance[1] = 2.0 / (1 << bufferBits[1]);
+   tolerance[2] = 2.0 / (1 << bufferBits[2]);
+   if (bufferBits[3])
+      tolerance[3] = 2.0 / (1 << bufferBits[3]);
+
+   else
+      tolerance[3] = 1.0;
+   if (bufferBits[4])
+      tolerance[4] = 16.0 / (1 << bufferBits[4]);
+
+   else
+      tolerance[4] = 1.0;
+}
+
+static void
+reportFailure(const char *programName, const GLfloat expectedColor[4],
+              const GLfloat actualColor[4])
+{
+   fprintf(stdout, "FAILURE:\n");
+   fprintf(stdout, "  Shader test: %s\n", programName);
+   fprintf(stdout, "  Expected color: [%1.3f, %1.3f, %1.3f, %1.3f]\n",
+           expectedColor[0], expectedColor[1], expectedColor[2],
+           expectedColor[3]);
+   fprintf(stdout, "  Observed color: [%1.3f, %1.3f, %1.3f, %1.3f]\n",
+           actualColor[0], actualColor[1], actualColor[2], actualColor[3]);
+} static GLboolean
+
+equalColors(const GLfloat act[4], const GLfloat exp[4])
+{
+   const GLfloat *tol = tolerance;
+   if ((fabsf(act[0] - exp[0]) > tol[0]) ||
+       (fabsf(act[1] - exp[1]) > tol[1]) ||
+       (fabsf(act[2] - exp[2]) > tol[2]) || (fabsf(act[3] - exp[3]) > tol[3]))
+      return GL_FALSE;
+
+   else
+      return GL_TRUE;
+}
+
+static GLuint
+loadAndCompileShader(GLenum target, const char *str)
+{
+   GLuint shader;
+   shader = glCreateShader(target);
+   glShaderSource(shader, 1, (const GLchar **) &str, NULL);
+   glCompileShader(shader);
+   return shader;
+}
+
+static GLboolean
+checkCompileStatus(GLenum target, GLuint shader, struct ShaderProgram p)
+{
+   GLint stat;
+   GLchar infoLog[1000];
+   GLsizei len;
+   glGetShaderiv(shader, GL_COMPILE_STATUS, &stat);
+   if (!stat) {
+      glGetShaderInfoLog(shader, 1000, &len, infoLog);
+      fprintf(stderr, "FAILURE:\n");
+      fprintf(stderr, "  Shader test: %s\n", p.name);
+      if (target == GL_FRAGMENT_SHADER)
+         fprintf(stderr, "Fragment shader did not compile:\n");
+
+      else
+         fprintf(stderr, "Vertex shader did not compile:\n");;
+      fprintf(stderr, "%s\n", infoLog);
+      return GL_FALSE;
+   }
+   return GL_TRUE;
+}
+
+static GLboolean
+testProgram(struct ShaderProgram p)
+{
+   const GLfloat r = 0.62;      /* XXX draw 16x16 pixel quad */
+   GLuint fragShader = 0, vertShader = 0, program = 0;
+   GLint utexZ;
+   GLboolean retVal = GL_FALSE;
+   GLfloat pixel[4];
+   if (p.fragShaderString) {
+      fragShader =
+         loadAndCompileShader(GL_FRAGMENT_SHADER, p.fragShaderString);
+      if (!checkCompileStatus(GL_FRAGMENT_SHADER, fragShader, p)) {
+         retVal = GL_FALSE;
+         goto cleanup;
+      }
+   }
+   if (!fragShader && !vertShader) {
+
+      /* must have had a compilation errror */
+      retVal = GL_FALSE;
+      goto cleanup;
+   }
+   program = glCreateProgram();
+   if (fragShader)
+      glAttachShader(program, fragShader);
+   if (vertShader)
+      glAttachShader(program, vertShader);
+   glLinkProgram(program);
+
+   /* check link */
+   {
+      GLint stat;
+      glGetProgramiv(program, GL_LINK_STATUS, &stat);
+      if (!stat) {
+         GLchar log[1000];
+         GLsizei len;
+         glGetProgramInfoLog(program, 1000, &len, log);
+         fprintf(stderr, "FAILURE:\n");
+         fprintf(stderr, "  Shader test: %s\n", p.name);;
+         fprintf(stderr, "  Link error: ");;
+         fprintf(stderr, "%s\n", log);
+         retVal = GL_FALSE;
+         goto cleanup;
+      }
+   }
+   glUseProgram(program);
+
+   /* load uniform vars */
+   utexZ = glGetUniformLocation(program, "texZ");
+   assert(utexZ >= 0);
+   glUniform1i(utexZ, 0);       /* bind to tex unit 0 */
+
+   /* to avoid potential issue with undefined result.depth.z */
+   glDisable(GL_DEPTH_TEST);
+   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+   /* Counter Clockwise */
+   glBegin(GL_POLYGON);
+   glTexCoord2f(0, 0);
+   glVertex2f(-r, -r);
+   glTexCoord2f(1, 0);
+   glVertex2f(r, -r);
+   glTexCoord2f(1, 1);
+   glVertex2f(r, r);
+   glTexCoord2f(0, 1);
+   glVertex2f(-r, r);
+   glEnd();
+
+   /* read a pixel from lower-left corder of rendered quad */
+   glReadPixels(windowSize / 2 - 2, windowSize / 2 - 2, 1, 1, GL_RGBA,
+                GL_FLOAT, pixel);
+   if (!equalColors(pixel, p.expectedColor)) {
+      reportFailure(p.name, p.expectedColor, pixel);
+      retVal = GL_FALSE;
+      goto cleanup;
+   }
+
+   /* passed! */
+   retVal = GL_TRUE;
+
+ cleanup:
+   if (fragShader)
+      glDeleteShader(fragShader);
+   if (vertShader)
+      glDeleteShader(vertShader);
+   glDeleteProgram(program);
+   return retVal;
+}
+
+static void
+Display(void)
+{
+   int i, numPassed = 0, numFailed = 0;
+   for (i = 0; Programs[i].name; i++) {
+      if (testProgram(Programs[i])) {
+         numPassed++;
+      }
+
+      else {
+         numFailed++;
+      }
+      glFinish();
+   }
+   fprintf(stderr, "Total = %d. Passed = %d. Failed = %d\n",
+           numPassed + numFailed, numPassed, numFailed);
+}
+
+static void
+Reshape(int width, int height)
+{
+} static void
+
+Key(unsigned char key, int x, int y)
+{
+   (void) x;
+   (void) y;
+   switch (key) {
+   case 27:
+      exit(0);
+      break;
+   }
+   glutPostRedisplay();
+}
+
+int
+main(int argc, char *argv[])
+{
+   glutInit(&argc, argv);
+   glutInitWindowPosition(0, 0);
+   glutInitWindowSize(windowSize, windowSize);
+   glutInitDisplayMode(GLUT_DEPTH | GLUT_RGBA | GLUT_SINGLE | GLUT_ALPHA);
+   glutCreateWindow(argv[0]);
+   glewInit();
+   glutReshapeFunc(Reshape);
+   glutKeyboardFunc(Key);
+   glutDisplayFunc(Display);
+   Init();
+   glutMainLoop();
+   return 0;
+}



More information about the mesa-commit mailing list