summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolai Haehnle <nhaehnle@gmail.com>2008-08-15 19:32:53 +0200
committerNicolai Haehnle <nhaehnle@gmail.com>2008-08-15 19:32:53 +0200
commitd62c5606c32be64e8a69a1e9971559ffcfc5a295 (patch)
tree3f4d44e5fdc86bec342924a53a6cb10aaec34100
parent4534ddc2b094d930cb8f1db9fbf6ccaa114728e8 (diff)
New test: texturing/tex3d
This is a very basic test that creates 3D textures of varying sizes, renders them and compares the results with expected results. It's still quite incomplete, e.g. a test for TexSubImage and mipmapped textures is still missing.
-rw-r--r--tests/all.tests1
-rw-r--r--tests/texturing/CMakeLists.txt1
-rw-r--r--tests/texturing/tex3d.c251
3 files changed, 253 insertions, 0 deletions
diff --git a/tests/all.tests b/tests/all.tests
index b3eec1481..703b333d6 100644
--- a/tests/all.tests
+++ b/tests/all.tests
@@ -87,6 +87,7 @@ texturing = Group()
texturing['copytexsubimage'] = PlainExecTest([testBinDir + 'copytexsubimage', '-auto'])
texturing['cubemap'] = PlainExecTest([testBinDir + 'cubemap', '-auto'])
texturing['lodbias'] = PlainExecTest([testBinDir + 'lodbias', '-auto'])
+texturing['tex3d'] = PlainExecTest([testBinDir + 'tex3d'])
texturing['texdepth'] = PlainExecTest([testBinDir + 'texdepth', '-auto'])
texturing['texrect-many'] = PlainExecTest([testBinDir + 'texrect-many', '-auto'])
texturing['texredefine'] = PlainExecTest([testBinDir + 'texredefine', '-auto'])
diff --git a/tests/texturing/CMakeLists.txt b/tests/texturing/CMakeLists.txt
index 9a57de22e..ccf334e03 100644
--- a/tests/texturing/CMakeLists.txt
+++ b/tests/texturing/CMakeLists.txt
@@ -21,6 +21,7 @@ link_libraries (
add_executable (copytexsubimage copytexsubimage.c)
add_executable (cubemap cubemap.c)
add_executable (lodbias lodbias.c)
+add_executable (tex3d tex3d.c)
add_executable (texdepth texdepth.c)
add_executable (texrect-many texrect-many.c)
add_executable (texredefine texredefine.c)
diff --git a/tests/texturing/tex3d.c b/tests/texturing/tex3d.c
new file mode 100644
index 000000000..1d1084723
--- /dev/null
+++ b/tests/texturing/tex3d.c
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) The Piglit project 2008
+ *
+ * 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
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, 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 (including the next
+ * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS 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
+ * Tests 3D textures.
+ */
+
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <GL/glut.h>
+
+#include "piglit-util.h"
+
+static int Width = 128, Height = 128;
+static GLuint Texture;
+
+static int nrcomponents(GLenum format)
+{
+ switch(format) {
+ case GL_RGBA: return 4;
+ case GL_RGB: return 3;
+ case GL_ALPHA: return 1;
+ default: abort();
+ }
+}
+
+static const char* formatname(GLenum format)
+{
+ switch(format) {
+ case GL_RGBA: return "GL_RGBA";
+ case GL_RGB: return "GL_RGB";
+ case GL_ALPHA: return "GL_ALPHA";
+ default: abort();
+ }
+}
+
+static void expected_rgba(GLenum format, const unsigned char* texdata, unsigned char* expected)
+{
+ switch(format) {
+ case GL_RGBA:
+ expected[0] = texdata[0];
+ expected[1] = texdata[1];
+ expected[2] = texdata[2];
+ expected[3] = texdata[3];
+ return;
+ case GL_RGB:
+ expected[0] = texdata[0];
+ expected[1] = texdata[1];
+ expected[2] = texdata[2];
+ expected[3] = 255;
+ return;
+ case GL_ALPHA:
+ expected[0] = 255;
+ expected[1] = 255;
+ expected[2] = 255;
+ expected[3] = texdata[0];
+ return;
+ }
+}
+
+static int render_and_check(int w, int h, int d, GLenum format, float q, unsigned char* data, const char* test)
+{
+ int x, y, z;
+ int layer;
+ unsigned char* readback;
+ unsigned char* texp;
+ unsigned char* readp;
+ int ncomp;
+
+ glClearColor(0.0, 0.0, 0.0, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glEnable(GL_TEXTURE_3D);
+
+ x = y = 0;
+ for(layer = 0; layer < d; ++layer) {
+ float r = (layer+0.5)/d;
+ glBegin(GL_QUADS);
+ glTexCoord4f(0, 0, r*q, q);
+ glVertex2f(x, y);
+ glTexCoord4f(q, 0, r*q, q);
+ glVertex2f(x+w, y);
+ glTexCoord4f(q, q, r*q, q);
+ glVertex2f(x+w, y+h);
+ glTexCoord4f(0, q, r*q, q);
+ glVertex2f(x, y+h);
+ glEnd();
+ x += w;
+ if (x >= Width) {
+ y += h;
+ x = 0;
+ }
+ }
+ glutSwapBuffers();
+
+ readback = (unsigned char*)malloc(w*h*d*4);
+ x = y = 0;
+ for(layer = 0; layer < d; ++layer) {
+ glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, readback+layer*w*h*4);
+ x += w;
+ if (x >= Width) {
+ y += h;
+ x = 0;
+ }
+ }
+
+ texp = data;
+ readp = readback;
+ ncomp = nrcomponents(format);
+ for(z = 0; z < d; ++z) {
+ for(y = 0; y < h; ++y) {
+ for(x = 0; x < w; ++x, readp += 4, texp += ncomp) {
+ unsigned char expected[4];
+ int i;
+ expected_rgba(format, texp, expected);
+ for(i = 0; i < 4; ++i) {
+ if (expected[i] != readp[i]) {
+ fprintf(stderr, "%s: Mismatch at %ix%ix%i\n", test, x, y, z);
+ fprintf(stderr, " Expected: %i,%i,%i,%i\n",
+ expected[0], expected[1], expected[2], expected[3]);
+ fprintf(stderr, " Readback: %i,%i,%i,%i\n",
+ readp[0], readp[1], readp[2], readp[3]);
+ free(readback);
+ return 0;
+ }
+ }
+ }
+ }
+ }
+ free(readback);
+
+ return 1;
+}
+
+
+/**
+ * Load non-mipmapped 3D texture of the given size
+ * and check whether it is rendered correctly.
+ */
+static void test_simple(int w, int h, int d, GLenum format)
+{
+ int size;
+ unsigned char *data;
+ int i;
+ int success = 1;
+
+ assert(1 <= w && w <= 16);
+ assert(1 <= h && h <= 16);
+ assert(1 <= d && d <= 16);
+ assert(format == GL_RGBA || format == GL_RGB || format == GL_ALPHA);
+
+ size = w*h*d*nrcomponents(format);
+ data = (unsigned char*)malloc(size);
+
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+ srand(size); /* Generate reproducible image data */
+ for(i = 0; i < size; ++i)
+ data[i] = rand() & 255;
+
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexImage3D(GL_TEXTURE_3D, 0, format, w, h, d, 0, format, GL_UNSIGNED_BYTE, data);
+
+ success = success && render_and_check(w, h, d, format, 1.0, data, "Render 3D texture");
+ success = success && render_and_check(w, h, d, format, 1.4, data, "Render 3D texture (q != 1.0)");
+
+ free(data);
+
+ if (!success) {
+ fprintf(stderr, "Failure with texture size %ix%ix%i, format = %s\n",
+ w, h, d, formatname(format));
+ piglit_report_result(PIGLIT_FAILURE);
+ }
+}
+
+static void Redisplay(void)
+{
+ GLenum formats[] = { GL_RGBA, GL_RGB, GL_ALPHA };
+ int w, h, d, fmt;
+
+ for(fmt = 0; fmt < sizeof(formats)/sizeof(formats[0]); ++fmt) {
+ for(w = 1; w <= 16; w *= 2) {
+ for(h = 1; h <= 16; h *= 2) {
+ for(d = 1; d <= 16; d *= 2) {
+ test_simple(w, h, d, formats[fmt]);
+ }
+ }
+ }
+ }
+
+ piglit_report_result(PIGLIT_SUCCESS);
+}
+
+
+static void Reshape(int width, int height)
+{
+ glViewport(0, 0, Width, Height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0.0, Width, 0.0, Height, -1.0, 1.0);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+}
+
+
+static void Init(void)
+{
+ glGenTextures(1, &Texture);
+ glBindTexture(GL_TEXTURE_3D, Texture);
+ Reshape(Width,Height);
+}
+
+int main(int argc, char *argv[])
+{
+ int i;
+ glutInit(&argc, argv);
+ glutInitWindowPosition(0, 0);
+ glutInitWindowSize(Width, Height);
+ glutInitDisplayMode(GLUT_RGB | GLUT_ALPHA);
+ glutCreateWindow(argv[0]);
+ glutReshapeFunc(Reshape);
+ glutDisplayFunc(Redisplay);
+ Init();
+ glutMainLoop();
+ return 0;
+}
+