1 /* Copyright © 2005 Brian Paul
3 * Permission is hereby granted, free of charge, to any person obtaining a
4 * copy of this software and associated documentation files (the "Software"),
5 * to deal in the Software without restriction, including without limitation
6 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 * and/or sell copies of the Software, and to permit persons to whom the
8 * Software is furnished to do so, subject to the following conditions:
10 * The above copyright notice and this permission notice (including the next
11 * paragraph) shall be included in all copies or substantial portions of the
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 /** @file point-attenuation.c
25 * Test GL_ARB_point_parameters extension.
30 #include "piglit-util-gl.h"
32 #define windowWidth 100
33 #define windowHeight 503 /* yes, odd */
35 PIGLIT_GL_TEST_CONFIG_BEGIN
36 config
.supports_gl_compat_version
= 10;
37 config
.window_visual
= PIGLIT_GL_VISUAL_DOUBLE
| PIGLIT_GL_VISUAL_RGBA
;
38 config
.window_width
= windowWidth
;
39 config
.window_height
= windowHeight
;
40 PIGLIT_GL_TEST_CONFIG_END
42 /* Max tested point size */
45 /* Clamp X to [MIN,MAX] */
46 #define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) )
48 GLfloat aliasedLimits
[2]; /* min/max */
49 GLfloat smoothLimits
[2]; /* min/max */
52 reportFailure(GLfloat initSize
, const GLfloat attenuation
[3],
53 GLfloat min
, GLfloat max
, GLfloat eyeZ
,
54 GLfloat expected
, GLfloat actual
)
56 fprintf(stderr
, "Expected size: %f Actual size: %f\n", expected
, actual
);
57 fprintf(stderr
, "Size: %f\n", initSize
);
58 fprintf(stderr
, "Min: %f Max %f\n", min
, max
);
59 fprintf(stderr
, "Attenuation %f %f %f\n", attenuation
[0] , attenuation
[1], attenuation
[2]);
60 fprintf(stderr
, "Eye Z: %f\n", eyeZ
);
64 /* Compute the expected point size given various point state */
66 expectedSize(GLfloat initSize
,
67 const GLfloat attenuation
[3],
68 GLfloat min
, GLfloat max
,
69 GLfloat eyeZ
, GLboolean smooth
)
71 const GLfloat dist
= fabs(eyeZ
);
72 const GLfloat atten
= sqrt(1.0 / (attenuation
[0] +
73 attenuation
[1] * dist
+
74 attenuation
[2] * dist
* dist
));
76 float size
= initSize
* atten
;
78 size
= CLAMP(size
, min
, max
);
81 size
= CLAMP(size
, smoothLimits
[0], smoothLimits
[1]);
83 size
= CLAMP(size
, aliasedLimits
[0], aliasedLimits
[1]);
88 /* measure size of rendered point at yPos (in model coords) */
90 measureSize(GLfloat yPos
)
92 assert(yPos
>= -10.0);
94 float yNdc
= (yPos
+ 10.0) / 20.0; /* See glOrtho above */
96 int y
= (int) (yNdc
* windowHeight
);
99 GLfloat image
[3 * windowWidth
* 3]; /* three rows of RGB values */
101 /* Read three row of pixels and add up colors in each row.
102 * Use the row with the greatest sum. This helps gives us a bit
103 * of leeway in vertical point positioning.
104 * Colors should be white or shades of gray if smoothing is enabled.
106 glReadPixels(x
, y
- 1, w
, h
, GL_RGB
, GL_FLOAT
, image
);
108 float sum
[3] = { 0.0, 0.0, 0.0 };
109 for (int j
= 0; j
< 3; j
++) {
110 for (int i
= 0; i
< w
; i
++) {
111 int k
= j
* 3 * w
+ i
* 3;
112 sum
[j
] += (image
[k
+0] + image
[k
+1] + image
[k
+2]) / 3.0;
116 /* find max of the row sums */
117 if (sum
[0] >= sum
[1] && sum
[0] >= sum
[2])
119 else if (sum
[1] >= sum
[0] && sum
[1] >= sum
[2])
127 testPointRendering(bool smooth
)
129 /* epsilon is the allowed size difference in pixels between the
130 * expected and actual rendering.
132 const GLfloat epsilon
= (smooth
? 1.5 : 1.0) + 0.0;
136 glEnable(GL_POINT_SMOOTH
);
138 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
141 glDisable(GL_POINT_SMOOTH
);
145 for (int a
= 0; a
< 3; a
++) {
146 atten
[0] = pow(10.0, -a
);
147 for (int b
= -2; b
< 3; b
++) {
148 atten
[1] = (b
== -1) ? 0.0 : pow(10.0, -b
);
149 for (int c
= -2; c
< 3; c
++) {
150 atten
[2] = (c
== -1) ? 0.0 : pow(10.0, -c
);
151 glPointParameterfvARB(GL_POINT_DISTANCE_ATTENUATION_ARB
, atten
);
152 for (float min
= 1.0; min
< MAX_SIZE
; min
+= 10) {
153 glPointParameterfARB(GL_POINT_SIZE_MIN_ARB
, min
);
154 for (float max
= min
; max
< MAX_SIZE
; max
+= 10) {
155 glPointParameterfARB(GL_POINT_SIZE_MAX_ARB
, max
);
156 for (float size
= 1.0; size
< MAX_SIZE
; size
+= 8) {
159 /* draw column of points */
160 glClear(GL_COLOR_BUFFER_BIT
);
162 for (float z
= -6.0; z
<= 6.0; z
+= 1.0) {
167 /* test the column of points */
168 for (float z
= -6.0; z
<= 6.0; z
+= 1.0) {
170 = expectedSize(size
, atten
, min
, max
,
172 float actual
= measureSize(z
);
173 if (fabs(expected
- actual
) > epsilon
) {
174 reportFailure(size
, atten
, min
, max
,
175 z
, expected
, actual
);
179 printf("pass z=%f exp=%f act=%f\n",
180 z
, expected
, actual
);
190 if (!piglit_check_gl_error(0))
200 bool pass
= testPointRendering(smooth
);
201 piglit_report_subtest_result(pass
? PIGLIT_PASS
: PIGLIT_FAIL
,
202 "Antialiased combinations");
205 bool pass2
= testPointRendering(smooth
) && pass
;
206 piglit_report_subtest_result(pass2
? PIGLIT_PASS
: PIGLIT_FAIL
,
207 "Aliased combinations");
209 return pass
&& pass2
? PIGLIT_PASS
: PIGLIT_FAIL
;
213 piglit_init(int argc
, char **argv
)
215 piglit_require_extension("GL_ARB_point_parameters");
217 for (int i
= 0; i
< 2; i
++) {
218 aliasedLimits
[i
] = 0;
222 glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE
, aliasedLimits
);
223 glGetFloatv(GL_SMOOTH_POINT_SIZE_RANGE
, smoothLimits
);
224 glMatrixMode(GL_PROJECTION
);
226 glOrtho(-10.0, 10.0, -10.0, 10.0, -10.0, 10.0);
227 glMatrixMode(GL_MODELVIEW
);
230 if (!piglit_check_gl_error(0))
231 piglit_report_result(PIGLIT_FAIL
);