1 // BEGIN_COPYRIGHT -*- glean -*-
3 // Copyright (C) 2009 VMware, Inc. All Rights Reserved.
5 // Permission is hereby granted, free of charge, to any person
6 // obtaining a copy of this software and associated documentation
7 // files (the "Software"), to deal in the Software without
8 // restriction, including without limitation the rights to use,
9 // copy, modify, merge, publish, distribute, sublicense, and/or
10 // sell copies of the Software, and to permit persons to whom the
11 // Software is furnished to do so, subject to the following
14 // The above copyright notice and this permission notice shall be
15 // included in all copies or substantial portions of the
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
19 // KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
20 // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
21 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL VMWARE BE
22 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 // AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
24 // OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 // DEALINGS IN THE SOFTWARE.
30 // Test GL_EXT_texture_swizzle for all possible swizzle combinations
31 // both with fixed function and a fragment program.
36 #define GL_GLEXT_PROTOTYPES
42 #include "ttexswizzle.h"
50 static PFNGLPROGRAMSTRINGARBPROC glProgramStringARB_func
= NULL
;
51 static PFNGLBINDPROGRAMARBPROC glBindProgramARB_func
= NULL
;
52 static PFNGLGENPROGRAMSARBPROC glGenProgramsARB_func
= NULL
;
54 static const int TexSize
= 16;
56 static const GLfloat vertexData
[4][4] = {
58 { -1.0, -1.0, 0.0, 0.0 },
59 { 1.0, -1.0, 1.0, 0.0 },
60 { 1.0, 1.0, 1.0, 1.0 },
61 { -1.0, 1.0, 0.0, 1.0 }
65 TexSwizzleResult::TexSwizzleResult()
72 TexSwizzleTest::RandomColor(GLubyte
*color
)
74 color
[0] = rand
.next() & 0xff;
75 color
[1] = rand
.next() & 0xff;
76 color
[2] = rand
.next() & 0xff;
77 color
[3] = rand
.next() & 0xff;
82 TexSwizzleTest::SetTextureColor(const GLubyte
*color
)
84 GLubyte texImage
[TexSize
][TexSize
][4];
87 for (i
= 0; i
< TexSize
; i
++) {
88 for (j
= 0; j
< TexSize
; j
++) {
89 texImage
[i
][j
][0] = color
[0];
90 texImage
[i
][j
][1] = color
[1];
91 texImage
[i
][j
][2] = color
[2];
92 texImage
[i
][j
][3] = color
[3];
96 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA
, TexSize
, TexSize
, 0,
97 GL_RGBA
, GL_UNSIGNED_BYTE
, texImage
);
102 TexSwizzleTest::Swizzle(const GLubyte
*texColor
, GLenum swizzle
)
124 TexSwizzleTest::ComputeExpectedColor(const GLubyte
*texColor
,
129 GLubyte
*expectedColor
)
131 expectedColor
[0] = Swizzle(texColor
, swizzleR
);
132 expectedColor
[1] = Swizzle(texColor
, swizzleG
);
133 expectedColor
[2] = Swizzle(texColor
, swizzleB
);
134 expectedColor
[3] = Swizzle(texColor
, swizzleA
);
139 TexSwizzleTest::SwizzleString(GLenum swizzle
)
162 TexSwizzleTest::ReportFailure(GLenum swizzleR
, GLenum swizzleG
,
163 GLenum swizzleB
, GLenum swizzleA
,
164 const GLubyte
*texColor
,
165 const GLubyte
*actual
,
166 const GLubyte
*expected
)
170 env
->log
<< name
<< ": Error: GL_EXT_texure_swizzle test failed\n";
171 env
->log
<< "\tGL_TEXTURE_SWIZZLE_R_EXT = " << SwizzleString(swizzleR
) << "\n";
172 env
->log
<< "\tGL_TEXTURE_SWIZZLE_G_EXT = " << SwizzleString(swizzleG
) << "\n";
173 env
->log
<< "\tGL_TEXTURE_SWIZZLE_B_EXT = " << SwizzleString(swizzleB
) << "\n";
174 env
->log
<< "\tGL_TEXTURE_SWIZZLE_A_EXT = " << SwizzleString(swizzleA
) << "\n";
175 if (glIsEnabled(GL_FRAGMENT_PROGRAM_ARB
)) {
176 env
->log
<< "\tGL_FRAGMENT_PROGRAM enabled\n";
178 sprintf(str
, "%d, %d, %d, %d",
179 texColor
[0], texColor
[1], texColor
[2], texColor
[3]);
180 env
->log
<< "\tTexture color: " << str
<< "\n";
181 sprintf(str
, "%d, %d, %d, %d",
182 expected
[0], expected
[1], expected
[2], expected
[3]);
183 env
->log
<< "\tExpected color: " << str
<< "\n";
184 sprintf(str
, "%d, %d, %d, %d",
185 actual
[0], actual
[1], actual
[2], actual
[3]);
186 env
->log
<< "\tRendered color: " << str
<< "\n";
190 // Test state setting/getting for texture swizzle.
192 TexSwizzleTest::TestAPI(void)
194 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_SWIZZLE_R_EXT
, GL_ONE
);
195 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_SWIZZLE_G_EXT
, GL_ZERO
);
196 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_SWIZZLE_B_EXT
, GL_RED
);
197 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_SWIZZLE_A_EXT
, GL_BLUE
);
199 if (glGetError() != GL_NO_ERROR
) {
200 env
->log
<< "\tSetting GL_TEXTURE_SWIZZLE_R/G/B/A generated an error.\n";
205 glGetTexParameteriv(GL_TEXTURE_2D
, GL_TEXTURE_SWIZZLE_R_EXT
, &val
);
207 env
->log
<< "\tQuery of GL_TEXTURE_SWIZZLE_R_EXT failed.\n";
210 glGetTexParameteriv(GL_TEXTURE_2D
, GL_TEXTURE_SWIZZLE_G_EXT
, &val
);
211 if (val
!= GL_ZERO
) {
212 env
->log
<< "\tQuery of GL_TEXTURE_SWIZZLE_G_EXT failed.\n";
215 glGetTexParameteriv(GL_TEXTURE_2D
, GL_TEXTURE_SWIZZLE_B_EXT
, &val
);
217 env
->log
<< "\tQuery of GL_TEXTURE_SWIZZLE_B_EXT failed.\n";
220 glGetTexParameteriv(GL_TEXTURE_2D
, GL_TEXTURE_SWIZZLE_A_EXT
, &val
);
221 if (val
!= GL_BLUE
) {
222 env
->log
<< "\tQuery of GL_TEXTURE_SWIZZLE_A_EXT failed.\n";
227 const GLint swz
[4] = { GL_BLUE
, GL_GREEN
, GL_ALPHA
, GL_ZERO
};
228 glTexParameteriv(GL_TEXTURE_2D
, GL_TEXTURE_SWIZZLE_RGBA_EXT
, swz
);
229 if (glGetError() != GL_NO_ERROR
) {
230 env
->log
<< "\tSetting GL_TEXTURE_SWIZZLE_RGBA_EXT generated an error.\n";
235 glGetTexParameteriv(GL_TEXTURE_2D
, GL_TEXTURE_SWIZZLE_RGBA_EXT
, swzOut
);
236 if (swzOut
[0] != swz
[0] ||
237 swzOut
[1] != swz
[1] ||
238 swzOut
[2] != swz
[2] ||
239 swzOut
[3] != swz
[3]) {
240 env
->log
<< "\tQuerying GL_TEXTURE_SWIZZLE_RGBA_EXT failed.\n";
248 // Loop over all possible combinations of texture swizzles,
249 // drawing with a texture and checking if the results are correct.
250 // return true/false for pass/fail
252 TexSwizzleTest::TestSwizzles(void)
254 static const GLenum swizzles
[6] = {
255 GL_RED
, GL_GREEN
, GL_BLUE
, GL_ALPHA
, GL_ZERO
, GL_ONE
259 int err
= 1; // XXX this should be computed from framebuffer depth
261 for (ir
= 0; ir
< 6; ir
++) {
262 glTexParameteri(GL_TEXTURE_2D
,
263 GL_TEXTURE_SWIZZLE_R_EXT
,
265 for (ig
= 0; ig
< 6; ig
++) {
266 glTexParameteri(GL_TEXTURE_2D
,
267 GL_TEXTURE_SWIZZLE_G_EXT
,
270 // Setup random texture color here (not in the innermost loop
271 // for _every_ iteration) just to speed things up a bit.
272 RandomColor(texColor
);
273 SetTextureColor(texColor
);
275 for (ib
= 0; ib
< 6; ib
++) {
276 glTexParameteri(GL_TEXTURE_2D
,
277 GL_TEXTURE_SWIZZLE_B_EXT
,
279 for (ia
= 0; ia
< 6; ia
++) {
280 glTexParameteri(GL_TEXTURE_2D
,
281 GL_TEXTURE_SWIZZLE_A_EXT
,
285 ComputeExpectedColor(texColor
,
292 // draw something and read back a pixel
293 glDrawArrays(GL_TRIANGLE_FAN
, 0, 4);
295 glReadPixels(windowSize
/ 2, windowSize
/ 2, 1, 1,
296 GL_RGBA
, GL_UNSIGNED_BYTE
, actual
);
298 if (abs((int) actual
[0] - (int) expected
[0]) > err
||
299 abs((int) actual
[1] - (int) expected
[1]) > err
||
300 abs((int) actual
[2] - (int) expected
[2]) > err
) {
302 ReportFailure(swizzles
[ir
],
306 texColor
, actual
, expected
);
319 // Same test as above, but using a fragment program instead of fixed-function.
321 TexSwizzleTest::TestSwizzlesWithProgram(void)
325 "TEX result.color, fragment.texcoord[0], texture[0], 2D; \n"
329 glGenProgramsARB_func(1, &prog
);
330 glBindProgramARB_func(GL_FRAGMENT_PROGRAM_ARB
, prog
);
331 glProgramStringARB_func(GL_FRAGMENT_PROGRAM_ARB
, GL_PROGRAM_FORMAT_ASCII_ARB
,
332 strlen(text
), (const GLubyte
*) text
);
334 assert(glGetError() == GL_NO_ERROR
);
336 glEnable(GL_FRAGMENT_PROGRAM_ARB
);
338 bool pass
= TestSwizzles();
340 glDisable(GL_FRAGMENT_PROGRAM_ARB
);
347 TexSwizzleTest::Setup(void)
349 glProgramStringARB_func
= (PFNGLPROGRAMSTRINGARBPROC
) GLUtils::getProcAddress("glProgramStringARB");
350 assert(glProgramStringARB_func
);
351 glBindProgramARB_func
= (PFNGLBINDPROGRAMARBPROC
) GLUtils::getProcAddress("glBindProgramARB");
352 assert(glBindProgramARB_func
);
353 glGenProgramsARB_func
= (PFNGLGENPROGRAMSARBPROC
) GLUtils::getProcAddress("glGenProgramsARB");
354 assert(glGenProgramsARB_func
);
356 // setup transformation
357 glViewport(0, 0, windowSize
, windowSize
);
358 glMatrixMode(GL_MODELVIEW
);
360 glMatrixMode(GL_PROJECTION
);
363 // setup vertex arrays (draw textured quad)
364 glVertexPointer(2, GL_FLOAT
, 16, vertexData
);
365 glTexCoordPointer(2, GL_FLOAT
, 16, &vertexData
[0][2]);
366 glEnable(GL_VERTEX_ARRAY
);
367 glEnable(GL_TEXTURE_COORD_ARRAY
);
370 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
371 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
372 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_REPLACE
);
373 glEnable(GL_TEXTURE_2D
);
378 TexSwizzleTest::runOne(TexSwizzleResult
&r
, Window
&w
)
380 (void) w
; // silence warning
387 r
.pass
= TestSwizzles();
390 if (r
.pass
&& GLUtils::haveExtension("GL_ARB_fragment_program")) {
391 r
. pass
= TestSwizzlesWithProgram();
397 TexSwizzleTest::logOne(TexSwizzleResult
&r
)
404 env
->log
<< name
<< " FAIL\n";
410 TexSwizzleTest::compareOne(TexSwizzleResult
&oldR
,
411 TexSwizzleResult
&newR
)
413 comparePassFail(oldR
, newR
);
418 TexSwizzleResult::putresults(ostream
&s
) const
430 TexSwizzleResult::getresults(istream
&s
)
435 if (strcmp(result
, "FAIL") == 0) {
445 // The test object itself:
446 TexSwizzleTest
texSwizzleTest("texSwizzle", "window, rgb",
447 "GL_EXT_texture_swizzle",
448 "Test the GL_EXT_texture_swizzle extension.\n");