1 /* The original code is:
2  * Author: Edwin Moehlheinrich
3  * This piece of code is public domain, just don't get yourself killed.
4  *
5  * Subsequent modifications to the code is:
6  * Copyright © 2009 Intel Corporation
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and associated documentation files (the "Software"),
10  * to deal in the Software without restriction, including without limitation
11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12  * and/or sell copies of the Software, and to permit persons to whom the
13  * Software is furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice (including the next
16  * paragraph) shall be included in all copies or substantial portions of the
17  * Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25  * IN THE SOFTWARE.
26  *
27  * Authors:
28  *    Edwin Moehlheinrich
29  *    Eric Anholt <eric@anholt.net>
30  *
31  */
32 
33 #include "piglit-util-gl.h"
34 
35 PIGLIT_GL_TEST_CONFIG_BEGIN
36 
37 	config.supports_gl_compat_version = 10;
38 
39 	config.window_width = 800;
40 	config.window_height = 600;
41 	config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE;
42 
43 PIGLIT_GL_TEST_CONFIG_END
44 
45 /* Misbehaviour: first: the quads are not drawn in the correct order
46  * (darker equals closer to the viewer), second: the middle one is strangely
47  * distorted.
48  */
49 
50 static GLuint vs, fs, prog, shadow_vs, shadow_fs, shadow_prog;
51 static GLint shadowMap_location;
52 static GLint eye_projection_location, light_projection_location;
53 
54 enum piglit_result
piglit_display(void)55 piglit_display(void)
56 {
57 	GLuint shadow_texture;
58 	GLuint fbo;
59 	float matrix[] = {	2.0/2.0, 0.0, 0.0, 0.0,
60 				0.0, 2.0/2.0, 0.0, 0.0,
61 				0.0, 0.0, -2/10.0, -12.0/10,
62 				0.0, 0.0, 0.0, 1.0};
63 	float rect1_color[3] = {.3, .3, .3};
64 	float rect2_color_dark[3] = {.01, .01, .01};
65 	float rect2_color_bottom_rect1[3] = {.09, .09, .09};
66 	float rect3_color[3] = {.1, .1, .1};
67 	GLboolean pass = GL_TRUE;
68 
69 	glEnable(GL_CULL_FACE);
70 	glEnable(GL_DEPTH_TEST);
71 	glClearDepth(1.0f);
72     	glDepthFunc(GL_LEQUAL);
73 
74 	/* Create empty 512x512 depth texture */
75 	glActiveTexture(GL_TEXTURE0);
76 	glGenTextures(1, &shadow_texture);
77 	glBindTexture(GL_TEXTURE_2D, shadow_texture);
78 	glTexImage2D(GL_TEXTURE_2D, 0,
79 		     GL_DEPTH_COMPONENT,
80 		     512, 512, 0,
81 		     GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
82 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
83 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
84 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
85 	glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);
86 
87 	glGenFramebuffersEXT(1, &fbo);
88 
89 	/* Render to the depth texture */
90 	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
91 	glDrawBuffer(GL_NONE);
92 	glReadBuffer(GL_NONE);
93 	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
94 				  GL_DEPTH_ATTACHMENT_EXT,
95 				  GL_TEXTURE_2D,
96 				  shadow_texture,
97 				  0);
98 
99 	glViewport(0, 0, 512, 512);
100 	glClear(GL_DEPTH_BUFFER_BIT);
101 	glUseProgram(shadow_prog);
102 	glUniform1i(shadowMap_location, 0);
103 	/* ogl reads in col-vectors, so transform=true */
104 	glUniformMatrix4fv(light_projection_location,
105 			      1, GL_TRUE, matrix);
106 	glBegin(GL_QUADS);
107 		/* rect1 */
108 		glVertex3f(-0.4,   0.4,   -2.0);
109 		glVertex3f(-0.4,  -0.4,   -2.0);
110 		glVertex3f(0.4,  -0.4,   -2.0);
111 		glVertex3f(0.4,   0.4,   -2.0);
112 
113 		/* rect2 */
114 		glVertex3f(-0.2,   0.5,   -7.0);
115 		glVertex3f(-0.2,  -0.3,   -1.0);
116 		glVertex3f(0.6,  -0.3,   -1.0);
117 		glVertex3f(0.6,   0.5,   -7.0);
118 
119 		/* rect3 */
120 		glVertex3f(-0.0,   0.6,   -4.0);
121 		glVertex3f(-0.0,  -0.2,   -4.0);
122 		glVertex3f(0.8,  -0.2,   -4.0);
123 		glVertex3f(0.8,   0.6,   -4.0);
124 	glEnd();
125 
126 	/* bind back the backbuffer and display the depthmap */
127 	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, piglit_winsys_fbo);
128 	glViewport(0, 0, 600, 600);
129 	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
130 
131 	glActiveTextureARB(GL_TEXTURE0_ARB);
132 	glBindTexture(GL_TEXTURE_2D, shadow_texture);
133 
134 	glUseProgram(prog);
135 	glUniformMatrix4fv(eye_projection_location, 1, 1, matrix);
136 	/* this is the quad that is texturized with what we want to see */
137 	glBegin(GL_QUADS);
138 
139 		glTexCoord2d(0.0,1.0);
140 		glVertex3f(-0.9,   0.9,   -1);
141 
142 		glTexCoord2d(0.0,0.0);
143 		glVertex3f(-0.9,  -0.9,   -1);
144 
145 		glTexCoord2d(1.0,0.0);
146 		glVertex3f(0.9,  -0.9,   -1);
147 
148 		glTexCoord2d(1.0,1.0);
149 		glVertex3f(0.9,   0.9,   -1);
150 
151 	glEnd();
152 
153 	/* check that rect1 is present. */
154 	pass &= piglit_probe_pixel_rgb(500, 400, rect1_color);
155 	/* check that rect3 is present. */
156 	pass &= piglit_probe_pixel_rgb(220, 300, rect3_color);
157 	/* check that rect2 where greater than rect1 is not rendered */
158 	pass &= piglit_probe_pixel_rgb(450, 350, rect1_color);
159 	/* check that rect2 where greater than rect3 is not rendered */
160 	pass &= piglit_probe_pixel_rgb(270, 350, rect3_color);
161 	/* check that rect2 where less than rect3 is rendered */
162 	pass &= piglit_probe_pixel_rgb(270, 225, rect2_color_dark);
163 	/* check that rect2 where less than rect1 is rendered */
164 	pass &= piglit_probe_pixel_rgb(450, 250, rect2_color_bottom_rect1);
165 
166 	piglit_present_results();
167 
168 	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
169 }
170 
171 void
piglit_init(int argc,char ** argv)172 piglit_init(int argc, char **argv)
173 {
174 	const char *vs_source =
175 		"uniform mat4 eye_projection;"
176 		"varying vec2 texture_coords;"
177 		"void main()"
178 		"{"
179 		"	gl_Position = eye_projection * gl_Vertex;"
180 		"	texture_coords = gl_MultiTexCoord0.st;"
181 		"}";
182 	const char *fs_source =
183 		"uniform sampler2D shadowMap;"
184 		"varying vec2 texture_coords;"
185 		"void main()"
186 		"{"
187 		"	float map_depth = texture2D(shadowMap,texture_coords).a;"
188 		"	gl_FragColor =  vec4(1.0, 1.0, 1.0, 1.0)* map_depth;"
189 		"}";
190 	const char *vs_shadow_source =
191 		"uniform mat4 light_projection; "
192 		"void main() "
193 		"{"
194 		"	gl_Position = light_projection * gl_Vertex;"
195 		"}";
196 	const char *fs_shadow_source =
197 		"void main()"
198 		"{"
199 		"	gl_FragDepth = gl_FragCoord.z;"
200 		"}";
201 
202 	piglit_require_extension("GL_EXT_framebuffer_object");
203 	piglit_require_GLSL();
204 
205 	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_source);
206 	fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_source);
207 	prog = piglit_link_simple_program(vs, fs);
208 
209 	shadow_vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_shadow_source);
210 	shadow_fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_shadow_source);
211 	shadow_prog = piglit_link_simple_program(shadow_vs, shadow_fs);
212 
213 	eye_projection_location = glGetUniformLocation(prog,
214 							  "eye_projection");
215 	light_projection_location = glGetUniformLocation(shadow_prog,
216 							    "light_projection");
217 	shadowMap_location = glGetUniformLocation(shadow_prog, "shadowMap");
218 }
219