1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL (ES) Module
3 * -----------------------------------------------
4 *
5 * Copyright 2014 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Utilities for tests with gls::LongStressCase.
22 *//*--------------------------------------------------------------------*/
23
24 #include "glsLongStressTestUtil.hpp"
25 #include "tcuStringTemplate.hpp"
26 #include "deStringUtil.hpp"
27
28 #include "glw.h"
29
30 using de::toString;
31 using std::map;
32 using std::string;
33 using tcu::Mat2;
34 using tcu::Mat3;
35 using tcu::Mat4;
36 using tcu::Vec2;
37 using tcu::Vec3;
38 using tcu::Vec4;
39
40 namespace deqp
41 {
42 namespace gls
43 {
44 namespace LongStressTestUtil
45 {
46
47 template <int Size>
translationMat(const float v)48 static tcu::Matrix<float, Size, Size> translationMat(const float v)
49 {
50 tcu::Matrix<float, Size, Size> res(1.0f);
51 tcu::Vector<float, Size> col(v);
52 col[Size - 1] = 1.0f;
53 res.setColumn(Size - 1, col);
54 return res;
55 }
56
57 // Specializes certain template patterns in templ for GLSL version m_glslVersion; params in additionalParams (optional) are also included in the substitution.
substitute(const string & templ,const map<string,string> & additionalParams) const58 string ProgramLibrary::substitute(const string &templ, const map<string, string> &additionalParams) const
59 {
60 const bool isGLSL3 = m_glslVersion == glu::GLSL_VERSION_300_ES;
61 map<string, string> params;
62
63 params["FRAG_HEADER"] = isGLSL3 ? "#version 300 es\nlayout(location = 0) out mediump vec4 dEQP_FragColor;\n" : "";
64 params["VTX_HEADER"] = isGLSL3 ? "#version 300 es\n" : "";
65 params["VTX_IN"] = isGLSL3 ? "in" : "attribute";
66 params["VTX_OUT"] = isGLSL3 ? "out" : "varying";
67 params["FRAG_IN"] = isGLSL3 ? "in" : "varying";
68 params["FRAG_COLOR"] = isGLSL3 ? "dEQP_FragColor" : "gl_FragColor";
69 params["TEXTURE_2D_FUNC"] = isGLSL3 ? "texture" : "texture2D";
70 params["NS"] = "${NS}"; // \note Keep these as-is, they're handled by StressCase.
71
72 params.insert(additionalParams.begin(), additionalParams.end());
73
74 return tcu::StringTemplate(templ.c_str()).specialize(params);
75 }
76
substitute(const std::string & templ) const77 string ProgramLibrary::substitute(const std::string &templ) const
78 {
79 return substitute(templ, map<string, string>());
80 }
81
ProgramLibrary(const glu::GLSLVersion glslVersion)82 ProgramLibrary::ProgramLibrary(const glu::GLSLVersion glslVersion) : m_glslVersion(glslVersion)
83 {
84 DE_ASSERT(glslVersion == glu::GLSL_VERSION_100_ES || glslVersion == glu::GLSL_VERSION_300_ES);
85 }
86
generateBufferContext(const int numUnusedAttributes) const87 gls::ProgramContext ProgramLibrary::generateBufferContext(const int numUnusedAttributes) const
88 {
89 static const char *const vertexTemplate = "${VTX_HEADER}"
90 "${VTX_IN} highp vec3 a_position;\n"
91 "${VTX_UNUSED_INPUTS}"
92 "${VTX_OUT} mediump vec4 v_color;\n"
93 "\n"
94 "void main (void)\n"
95 "{\n"
96 " gl_Position = vec4(a_position, 1.0);\n"
97 " v_color = ${VTX_COLOR_EXPRESSION};\n"
98 "}\n";
99
100 static const char *const fragmentTemplate = "${FRAG_HEADER}"
101 "${FRAG_IN} mediump vec4 v_color;\n"
102 "\n"
103 "void main (void)\n"
104 "{\n"
105 " ${FRAG_COLOR} = v_color;\n"
106 "}\n";
107
108 map<string, string> firstLevelParams;
109
110 {
111 string vtxUnusedInputs;
112 string vtxColorExpr;
113 for (int i = 0; i < numUnusedAttributes; i++)
114 {
115 vtxUnusedInputs += "${VTX_IN} mediump vec4 a_in" + toString(i) + ";\n";
116 vtxColorExpr += string() + (i > 0 ? " + " : "") + "a_in" + toString(i);
117 }
118
119 firstLevelParams["VTX_UNUSED_INPUTS"] = substitute(vtxUnusedInputs);
120 firstLevelParams["VTX_COLOR_EXPRESSION"] = vtxColorExpr;
121 }
122
123 gls::ProgramContext context(substitute(vertexTemplate, firstLevelParams).c_str(),
124 substitute(fragmentTemplate).c_str(), "a_position");
125
126 context.attributes.push_back(gls::VarSpec("a_position", Vec3(-0.1f), Vec3(0.1f)));
127
128 for (int i = 0; i < numUnusedAttributes; i++)
129 context.attributes.push_back(
130 gls::VarSpec("a_in" + de::toString(i), Vec4(0.0f), Vec4(1.0f / (float)numUnusedAttributes)));
131
132 return context;
133 }
134
generateTextureContext(const int numTextures,const int texWid,const int texHei,const float positionFactor) const135 gls::ProgramContext ProgramLibrary::generateTextureContext(const int numTextures, const int texWid, const int texHei,
136 const float positionFactor) const
137 {
138 static const char *const vertexTemplate = "${VTX_HEADER}"
139 "${VTX_IN} highp vec3 a_position;\n"
140 "${VTX_IN} mediump vec2 a_texCoord;\n"
141 "${VTX_OUT} mediump vec2 v_texCoord;\n"
142 "uniform mediump mat4 u_posTrans;\n"
143 "\n"
144 "void main (void)\n"
145 "{\n"
146 " gl_Position = u_posTrans * vec4(a_position, 1.0);\n"
147 " v_texCoord = a_texCoord;\n"
148 "}\n";
149
150 static const char *const fragmentTemplate = "${FRAG_HEADER}"
151 "${FRAG_IN} mediump vec2 v_texCoord;\n"
152 "uniform mediump sampler2D u_sampler;\n"
153 "\n"
154 "void main (void)\n"
155 "{\n"
156 " ${FRAG_COLOR} = ${TEXTURE_2D_FUNC}(u_sampler, v_texCoord);\n"
157 "}\n";
158
159 gls::ProgramContext context(substitute(vertexTemplate).c_str(), substitute(fragmentTemplate).c_str(), "a_position");
160
161 context.attributes.push_back(gls::VarSpec("a_position", Vec3(-positionFactor), Vec3(positionFactor)));
162 context.attributes.push_back(gls::VarSpec("a_texCoord", Vec2(0.0f), Vec2(1.0f)));
163
164 context.uniforms.push_back(gls::VarSpec("u_sampler", 0));
165 context.uniforms.push_back(
166 gls::VarSpec("u_posTrans", translationMat<4>(positionFactor - 1.0f), translationMat<4>(1.0f - positionFactor)));
167
168 for (int i = 0; i < numTextures; i++)
169 context.textureSpecs.push_back(gls::TextureSpec(
170 glu::TextureTestUtil::TEXTURETYPE_2D, 0, texWid, texHei, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA, true,
171 GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT, Vec4(0.0f), Vec4(1.0f)));
172
173 return context;
174 }
175
generateBufferAndTextureContext(const int numTextures,const int texWid,const int texHei) const176 gls::ProgramContext ProgramLibrary::generateBufferAndTextureContext(const int numTextures, const int texWid,
177 const int texHei) const
178 {
179 static const char *const vertexTemplate = "${VTX_HEADER}"
180 "${VTX_IN} highp vec3 a_position;\n"
181 "${VTX_TEX_COORD_INPUTS}"
182 "${VTX_TEX_COORD_OUTPUTS}"
183 "\n"
184 "void main (void)\n"
185 "{\n"
186 " gl_Position = vec4(a_position, 1.0);\n"
187 "${VTX_TEX_COORD_WRITES}"
188 "}\n";
189
190 static const char *const fragmentTemplate = "${FRAG_HEADER}"
191 "${FRAG_TEX_COORD_INPUTS}"
192 "${FRAG_SAMPLERS}"
193 "\n"
194 "void main (void)\n"
195 "{\n"
196 " ${FRAG_COLOR} =${FRAG_COLOR_EXPRESSION};\n"
197 "}\n";
198
199 map<string, string> firstLevelParams;
200
201 {
202 string vtxTexCoordInputs;
203 string vtxTexCoordOutputs;
204 string vtxTexCoordWrites;
205 string fragTexCoordInputs;
206 string fragSamplers;
207 string fragColorExpression;
208
209 for (int i = 0; i < numTextures; i++)
210 {
211 vtxTexCoordInputs += "${VTX_IN} mediump vec2 a_texCoord" + toString(i) + ";\n";
212 vtxTexCoordOutputs += "${VTX_OUT} mediump vec2 v_texCoord" + toString(i) + ";\n";
213 vtxTexCoordWrites += "\tv_texCoord" + toString(i) + " = " + "a_texCoord" + toString(i) + ";\n";
214 fragTexCoordInputs += "${FRAG_IN} mediump vec2 v_texCoord" + toString(i) + ";\n";
215 fragSamplers += "uniform mediump sampler2D u_sampler" + toString(i) + ";\n";
216 fragColorExpression += string() + (i > 0 ? " +" : "") + "\n\t\t${TEXTURE_2D_FUNC}(u_sampler" + toString(i) +
217 ", v_texCoord" + toString(i) + ")";
218 }
219
220 firstLevelParams["VTX_TEX_COORD_INPUTS"] = substitute(vtxTexCoordInputs);
221 firstLevelParams["VTX_TEX_COORD_OUTPUTS"] = substitute(vtxTexCoordOutputs);
222 firstLevelParams["VTX_TEX_COORD_WRITES"] = vtxTexCoordWrites;
223 firstLevelParams["FRAG_TEX_COORD_INPUTS"] = substitute(fragTexCoordInputs);
224 firstLevelParams["FRAG_SAMPLERS"] = fragSamplers;
225 firstLevelParams["FRAG_COLOR_EXPRESSION"] = substitute(fragColorExpression);
226 }
227
228 gls::ProgramContext context(substitute(vertexTemplate, firstLevelParams).c_str(),
229 substitute(fragmentTemplate, firstLevelParams).c_str(), "a_position");
230
231 context.attributes.push_back(gls::VarSpec("a_position", Vec3(-0.1f), Vec3(0.1f)));
232
233 for (int i = 0; i < numTextures; i++)
234 {
235 context.attributes.push_back(gls::VarSpec("a_texCoord" + de::toString(i), Vec2(0.0f), Vec2(1.0f)));
236 context.uniforms.push_back(gls::VarSpec("u_sampler" + de::toString(i), i));
237 context.textureSpecs.push_back(gls::TextureSpec(
238 glu::TextureTestUtil::TEXTURETYPE_2D, i, texWid, texHei, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA, true,
239 GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT, Vec4(0.0f), Vec4(1.0f / (float)numTextures)));
240 }
241
242 return context;
243 }
244
generateFragmentPointLightContext(const int texWid,const int texHei) const245 gls::ProgramContext ProgramLibrary::generateFragmentPointLightContext(const int texWid, const int texHei) const
246 {
247 static const char *const vertexTemplate =
248 "${VTX_HEADER}"
249 "struct Material\n"
250 "{\n"
251 " mediump vec3 ambientColor;\n"
252 " mediump vec4 diffuseColor;\n"
253 " mediump vec3 emissiveColor;\n"
254 " mediump vec3 specularColor;\n"
255 " mediump float shininess;\n"
256 "};\n"
257 "\n"
258 "struct Light\n"
259 "{\n"
260 " mediump vec3 color;\n"
261 " mediump vec4 position;\n"
262 " mediump vec3 direction;\n"
263 " mediump float constantAttenuation;\n"
264 " mediump float linearAttenuation;\n"
265 " mediump float quadraticAttenuation;\n"
266 "};\n"
267 "\n"
268 "${VTX_IN} highp vec4 a_position${NS};\n"
269 "${VTX_IN} mediump vec3 a_normal${NS};\n"
270 "${VTX_IN} mediump vec3 a_color${NS};\n"
271 "${VTX_IN} mediump vec4 a_texCoord0${NS};\n"
272 "\n"
273 "uniform Material u_material${NS};\n"
274 "uniform Light u_light${NS}[1];\n"
275 "uniform highp mat4 u_mvpMatrix${NS};\n"
276 "uniform mediump mat4 u_modelViewMatrix${NS};\n"
277 "uniform mediump mat3 u_normalMatrix${NS};\n"
278 "uniform mediump mat4 u_texCoordMatrix0${NS};\n"
279 "\n"
280 "${VTX_OUT} mediump vec4 v_baseColor${NS};\n"
281 "${VTX_OUT} mediump vec2 v_texCoord0${NS};\n"
282 "\n"
283 "${VTX_OUT} mediump vec3 v_eyeNormal${NS};\n"
284 "${VTX_OUT} mediump vec3 v_directionToLight${NS}[1];\n"
285 "${VTX_OUT} mediump float v_distanceToLight${NS}[1];\n"
286 "\n"
287 "vec3 direction (vec4 from, vec4 to)\n"
288 "{\n"
289 " return vec3(to.xyz * from.w - from.xyz * to.w);\n"
290 "}\n"
291 "\n"
292 "void main (void)\n"
293 "{\n"
294 " gl_Position = u_mvpMatrix${NS} * a_position${NS};\n"
295 " v_texCoord0${NS} = (u_texCoordMatrix0${NS} * a_texCoord0${NS}).xy;\n"
296 "\n"
297 " mediump vec4 eyePosition = u_modelViewMatrix${NS} * a_position${NS};\n"
298 " mediump vec3 eyeNormal = normalize(u_normalMatrix${NS} * a_normal${NS});\n"
299 "\n"
300 " vec4 color = vec4(0.0, 0.0, 0.0, 1.0);\n"
301 " color.rgb += u_material${NS}.emissiveColor;\n"
302 "\n"
303 " color.a *= u_material${NS}.diffuseColor.a;\n"
304 "\n"
305 " v_baseColor${NS} = color;\n"
306 "\n"
307 " v_distanceToLight${NS}[0] = distance(eyePosition, u_light${NS}[0].position);\n"
308 " v_directionToLight${NS}[0] = normalize(direction(eyePosition, u_light${NS}[0].position));\n"
309 "\n"
310 " v_eyeNormal${NS} = eyeNormal;\n"
311 "}\n";
312
313 static const char *const fragmentTemplate =
314 "${FRAG_HEADER}"
315 "struct Light\n"
316 "{\n"
317 " mediump vec3 color;\n"
318 " mediump vec4 position;\n"
319 " mediump vec3 direction;\n"
320 " mediump float constantAttenuation;\n"
321 " mediump float linearAttenuation;\n"
322 " mediump float quadraticAttenuation;\n"
323 "};\n"
324 "\n"
325 "struct Material\n"
326 "{\n"
327 " mediump vec3 ambientColor;\n"
328 " mediump vec4 diffuseColor;\n"
329 " mediump vec3 emissiveColor;\n"
330 " mediump vec3 specularColor;\n"
331 " mediump float shininess;\n"
332 "};\n"
333 "\n"
334 "uniform sampler2D u_sampler0${NS};\n"
335 "uniform Light u_light${NS}[1];\n"
336 "uniform Material u_material${NS};\n"
337 "\n"
338 "${FRAG_IN} mediump vec4 v_baseColor${NS};\n"
339 "${FRAG_IN} mediump vec2 v_texCoord0${NS};\n"
340 "\n"
341 "${FRAG_IN} mediump vec3 v_eyeNormal${NS};\n"
342 "${FRAG_IN} mediump vec3 v_directionToLight${NS}[1];\n"
343 "${FRAG_IN} mediump float v_distanceToLight${NS}[1];\n"
344 "\n"
345 "mediump vec3 computeLighting (Light light, mediump vec3 directionToLight, mediump vec3 vertexEyeNormal)\n"
346 "{\n"
347 " mediump float normalDotDirection = max(dot(vertexEyeNormal, directionToLight), 0.0);\n"
348 " mediump vec3 color = normalDotDirection * u_material${NS}.diffuseColor.rgb * "
349 "light.color;\n"
350 "\n"
351 " if (normalDotDirection != 0.0)\n"
352 " {\n"
353 " mediump vec3 h = normalize(directionToLight + vec3(0.0, 0.0, 1.0));\n"
354 " color.rgb += pow(max(dot(vertexEyeNormal, h), 0.0), u_material${NS}.shininess) * "
355 "u_material${NS}.specularColor * light.color;\n"
356 " }\n"
357 "\n"
358 " return color;\n"
359 "}\n"
360 "\n"
361 "mediump float computePointLightAttenuation (Light light, mediump float distanceToLight)\n"
362 "{\n"
363 " mediump float constantAttenuation = light.constantAttenuation;\n"
364 " mediump float linearAttenuation = light.linearAttenuation * distanceToLight;\n"
365 " mediump float quadraticAttenuation = light.quadraticAttenuation * distanceToLight * distanceToLight;\n"
366 "\n"
367 " return 1.0 / (constantAttenuation + linearAttenuation + quadraticAttenuation);\n"
368 "}\n"
369 "\n"
370 "void main (void)\n"
371 "{\n"
372 " mediump vec3 eyeNormal = normalize(v_eyeNormal${NS});\n"
373 " mediump vec4 color = v_baseColor${NS};\n"
374 "\n"
375 " color.rgb += computePointLightAttenuation(u_light${NS}[0], v_distanceToLight${NS}[0]) * "
376 "computeLighting(u_light${NS}[0], normalize(v_directionToLight${NS}[0]), eyeNormal);\n"
377 "\n"
378 " color *= ${TEXTURE_2D_FUNC}(u_sampler0${NS}, v_texCoord0${NS});\n"
379 "\n"
380 " ${FRAG_COLOR} = color;\n"
381 "}\n";
382
383 gls::ProgramContext context(substitute(vertexTemplate).c_str(), substitute(fragmentTemplate).c_str(),
384 "a_position${NS}");
385
386 context.attributes.push_back(gls::VarSpec("a_position${NS}", Vec4(-1.0f), Vec4(1.0f)));
387 context.attributes.push_back(gls::VarSpec("a_normal${NS}", Vec3(-1.0f), Vec3(1.0f)));
388 context.attributes.push_back(gls::VarSpec("a_texCoord0${NS}", Vec4(-1.0f), Vec4(1.0f)));
389
390 context.uniforms.push_back(gls::VarSpec("u_material${NS}.ambientColor", Vec3(0.0f), Vec3(1.0f)));
391 context.uniforms.push_back(gls::VarSpec("u_material${NS}.diffuseColor", Vec4(0.0f), Vec4(1.0f)));
392 context.uniforms.push_back(gls::VarSpec("u_material${NS}.emissiveColor", Vec3(0.0f), Vec3(1.0f)));
393 context.uniforms.push_back(gls::VarSpec("u_material${NS}.specularColor", Vec3(0.0f), Vec3(1.0f)));
394 context.uniforms.push_back(gls::VarSpec("u_material${NS}.shininess", 0.0f, 1.0f));
395
396 context.uniforms.push_back(gls::VarSpec("u_light${NS}[0].color", Vec3(0.0f), Vec3(1.0f)));
397 context.uniforms.push_back(gls::VarSpec("u_light${NS}[0].position", Vec4(-1.0f), Vec4(1.0f)));
398 context.uniforms.push_back(gls::VarSpec("u_light${NS}[0].direction", Vec3(-1.0f), Vec3(1.0f)));
399 context.uniforms.push_back(gls::VarSpec("u_light${NS}[0].constantAttenuation", 0.1f, 1.0f));
400 context.uniforms.push_back(gls::VarSpec("u_light${NS}[0].linearAttenuation", 0.1f, 1.0f));
401 context.uniforms.push_back(gls::VarSpec("u_light${NS}[0].quadraticAttenuation", 0.1f, 1.0f));
402
403 context.uniforms.push_back(gls::VarSpec("u_mvpMatrix${NS}", translationMat<4>(-0.2f), translationMat<4>(0.2f)));
404 context.uniforms.push_back(
405 gls::VarSpec("u_modelViewMatrix${NS}", translationMat<4>(-0.2f), translationMat<4>(0.2f)));
406 context.uniforms.push_back(gls::VarSpec("u_normalMatrix${NS}", translationMat<3>(-0.2f), translationMat<3>(0.2f)));
407 context.uniforms.push_back(
408 gls::VarSpec("u_texCoordMatrix0${NS}", translationMat<4>(-0.2f), translationMat<4>(0.2f)));
409
410 context.uniforms.push_back(gls::VarSpec("u_sampler0${NS}", 0));
411
412 context.textureSpecs.push_back(gls::TextureSpec(glu::TextureTestUtil::TEXTURETYPE_2D, 0, texWid, texHei, GL_RGBA,
413 GL_UNSIGNED_BYTE, GL_RGBA, true, GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR,
414 GL_REPEAT, GL_REPEAT, Vec4(0.0f), Vec4(1.0f)));
415
416 return context;
417 }
418
generateVertexUniformLoopLightContext(const int texWid,const int texHei) const419 gls::ProgramContext ProgramLibrary::generateVertexUniformLoopLightContext(const int texWid, const int texHei) const
420 {
421 static const char *const vertexTemplate =
422 "${VTX_HEADER}"
423 "struct Material {\n"
424 " mediump vec3 ambientColor;\n"
425 " mediump vec4 diffuseColor;\n"
426 " mediump vec3 emissiveColor;\n"
427 " mediump vec3 specularColor;\n"
428 " mediump float shininess;\n"
429 "};\n"
430 "struct Light {\n"
431 " mediump vec3 color;\n"
432 " mediump vec4 position;\n"
433 " mediump vec3 direction;\n"
434 " mediump float constantAttenuation;\n"
435 " mediump float linearAttenuation;\n"
436 " mediump float quadraticAttenuation;\n"
437 " mediump float spotExponent;\n"
438 " mediump float spotCutoff;\n"
439 "};\n"
440 "${VTX_IN} highp vec4 a_position${NS};\n"
441 "${VTX_IN} mediump vec3 a_normal${NS};\n"
442 "${VTX_IN} mediump vec4 a_texCoord0${NS};\n"
443 "uniform Material u_material${NS};\n"
444 "uniform Light u_directionalLight${NS}[1];\n"
445 "uniform mediump int u_directionalLightCount${NS};\n"
446 "uniform Light u_spotLight${NS}[4];\n"
447 "uniform mediump int u_spotLightCount${NS};\n"
448 "uniform highp mat4 u_mvpMatrix${NS};\n"
449 "uniform highp mat4 u_modelViewMatrix${NS};\n"
450 "uniform mediump mat3 u_normalMatrix${NS};\n"
451 "uniform mediump mat4 u_texCoordMatrix0${NS};\n"
452 "${VTX_OUT} mediump vec4 v_color${NS};\n"
453 "${VTX_OUT} mediump vec2 v_texCoord0${NS};\n"
454 "mediump vec3 direction (mediump vec4 from, mediump vec4 to)\n"
455 "{\n"
456 " return vec3(to.xyz * from.w - from.xyz * to.w);\n"
457 "}\n"
458 "\n"
459 "mediump vec3 computeLighting (\n"
460 " mediump vec3 directionToLight,\n"
461 " mediump vec3 halfVector,\n"
462 " mediump vec3 normal,\n"
463 " mediump vec3 lightColor,\n"
464 " mediump vec3 diffuseColor,\n"
465 " mediump vec3 specularColor,\n"
466 " mediump float shininess)\n"
467 "{\n"
468 " mediump float normalDotDirection = max(dot(normal, directionToLight), 0.0);\n"
469 " mediump vec3 color = normalDotDirection * diffuseColor * lightColor;\n"
470 "\n"
471 " if (normalDotDirection != 0.0)\n"
472 " color += pow(max(dot(normal, halfVector), 0.0), shininess) * specularColor * lightColor;\n"
473 "\n"
474 " return color;\n"
475 "}\n"
476 "\n"
477 "mediump float computeDistanceAttenuation (mediump float distToLight, mediump float constAtt, mediump float "
478 "linearAtt, mediump float quadraticAtt)\n"
479 "{\n"
480 " return 1.0 / (constAtt + linearAtt * distToLight + quadraticAtt * distToLight * distToLight);\n"
481 "}\n"
482 "\n"
483 "mediump float computeSpotAttenuation (\n"
484 " mediump vec3 directionToLight,\n"
485 " mediump vec3 lightDir,\n"
486 " mediump float spotExponent,\n"
487 " mediump float spotCutoff)\n"
488 "{\n"
489 " mediump float spotEffect = dot(lightDir, normalize(-directionToLight));\n"
490 "\n"
491 " if (spotEffect < spotCutoff)\n"
492 " spotEffect = 0.0;\n"
493 "\n"
494 " spotEffect = pow(spotEffect, spotExponent);\n"
495 " return spotEffect;\n"
496 "}\n"
497 "\n"
498 "void main (void)\n"
499 "{\n"
500 " highp vec4 position = a_position${NS};\n"
501 " highp vec3 normal = a_normal${NS};\n"
502 " gl_Position = u_mvpMatrix${NS} * position;\n"
503 " v_texCoord0${NS} = (u_texCoordMatrix0${NS} * a_texCoord0${NS}).xy;\n"
504 " mediump vec4 color = vec4(u_material${NS}.emissiveColor, u_material${NS}.diffuseColor.a);\n"
505 "\n"
506 " highp vec4 eyePosition = u_modelViewMatrix${NS} * position;\n"
507 " mediump vec3 eyeNormal = normalize(u_normalMatrix${NS} * normal);\n"
508 " for (int i = 0; i < u_directionalLightCount${NS}; i++)\n"
509 " {\n"
510 " mediump vec3 directionToLight = -u_directionalLight${NS}[i].direction;\n"
511 " mediump vec3 halfVector = normalize(directionToLight + vec3(0.0, 0.0, 1.0));\n"
512 " color.rgb += computeLighting(directionToLight, halfVector, eyeNormal, "
513 "u_directionalLight${NS}[i].color, u_material${NS}.diffuseColor.rgb, u_material${NS}.specularColor, "
514 "u_material${NS}.shininess);\n"
515 " }\n"
516 "\n"
517 " for (int i = 0; i < u_spotLightCount${NS}; i++)\n"
518 " {\n"
519 " mediump float distanceToLight = distance(eyePosition, u_spotLight${NS}[i].position);\n"
520 " mediump vec3 directionToLight = normalize(direction(eyePosition, u_spotLight${NS}[i].position));\n"
521 " mediump vec3 halfVector = normalize(directionToLight + vec3(0.0, 0.0, 1.0));\n"
522 " color.rgb += computeLighting(directionToLight, halfVector, eyeNormal, u_spotLight${NS}[i].color, "
523 "u_material${NS}.diffuseColor.rgb, u_material${NS}.specularColor, u_material${NS}.shininess) * "
524 "computeDistanceAttenuation(distanceToLight, u_spotLight${NS}[i].constantAttenuation, "
525 "u_spotLight${NS}[i].linearAttenuation, u_spotLight${NS}[i].quadraticAttenuation) * "
526 "computeSpotAttenuation(directionToLight, u_spotLight${NS}[i].direction, u_spotLight${NS}[i].spotExponent, "
527 "u_spotLight${NS}[i].spotCutoff);\n"
528 " }\n"
529 "\n"
530 "\n"
531 " v_color${NS} = color;\n"
532 "}\n";
533
534 static const char *const fragmentTemplate = "${FRAG_HEADER}"
535 "uniform sampler2D u_sampler0${NS};\n"
536 "${FRAG_IN} mediump vec4 v_color${NS};\n"
537 "${FRAG_IN} mediump vec2 v_texCoord0${NS};\n"
538 "void main (void)\n"
539 "{\n"
540 " mediump vec2 texCoord0 = v_texCoord0${NS};\n"
541 " mediump vec4 color = v_color${NS};\n"
542 " color *= ${TEXTURE_2D_FUNC}(u_sampler0${NS}, texCoord0);\n"
543 " ${FRAG_COLOR} = color;\n"
544 "}\n";
545
546 gls::ProgramContext context(substitute(vertexTemplate).c_str(), substitute(fragmentTemplate).c_str(),
547 "a_position${NS}");
548
549 context.attributes.push_back(gls::VarSpec("a_position${NS}", Vec4(-1.0f), Vec4(1.0f)));
550 context.attributes.push_back(gls::VarSpec("a_normal${NS}", Vec3(-1.0f), Vec3(1.0f)));
551 context.attributes.push_back(gls::VarSpec("a_texCoord0${NS}", Vec4(-1.0f), Vec4(1.0f)));
552
553 context.uniforms.push_back(gls::VarSpec("u_material${NS}.ambientColor", Vec3(0.0f), Vec3(1.0f)));
554 context.uniforms.push_back(gls::VarSpec("u_material${NS}.diffuseColor", Vec4(0.0f), Vec4(1.0f)));
555 context.uniforms.push_back(gls::VarSpec("u_material${NS}.emissiveColor", Vec3(0.0f), Vec3(1.0f)));
556 context.uniforms.push_back(gls::VarSpec("u_material${NS}.specularColor", Vec3(0.0f), Vec3(1.0f)));
557 context.uniforms.push_back(gls::VarSpec("u_material${NS}.shininess", 0.0f, 1.0f));
558
559 context.uniforms.push_back(gls::VarSpec("u_directionalLight${NS}[0].color", Vec3(0.0f), Vec3(1.0f)));
560 context.uniforms.push_back(gls::VarSpec("u_directionalLight${NS}[0].position", Vec4(-1.0f), Vec4(1.0f)));
561 context.uniforms.push_back(gls::VarSpec("u_directionalLight${NS}[0].direction", Vec3(-1.0f), Vec3(1.0f)));
562 context.uniforms.push_back(gls::VarSpec("u_directionalLight${NS}[0].constantAttenuation", 0.1f, 1.0f));
563 context.uniforms.push_back(gls::VarSpec("u_directionalLight${NS}[0].linearAttenuation", 0.1f, 1.0f));
564 context.uniforms.push_back(gls::VarSpec("u_directionalLight${NS}[0].quadraticAttenuation", 0.1f, 1.0f));
565 context.uniforms.push_back(gls::VarSpec("u_directionalLight${NS}[0].spotExponent", 0.1f, 1.0f));
566 context.uniforms.push_back(gls::VarSpec("u_directionalLight${NS}[0].spotCutoff", 0.1f, 1.0f));
567
568 context.uniforms.push_back(gls::VarSpec("u_directionalLightCount${NS}", 1));
569
570 for (int i = 0; i < 4; i++)
571 {
572 const std::string ndxStr = de::toString(i);
573
574 context.uniforms.push_back(gls::VarSpec("u_spotLight${NS}[" + ndxStr + "].color", Vec3(0.0f), Vec3(1.0f)));
575 context.uniforms.push_back(gls::VarSpec("u_spotLight${NS}[" + ndxStr + "].position", Vec4(-1.0f), Vec4(1.0f)));
576 context.uniforms.push_back(gls::VarSpec("u_spotLight${NS}[" + ndxStr + "].direction", Vec3(-1.0f), Vec3(1.0f)));
577 context.uniforms.push_back(gls::VarSpec("u_spotLight${NS}[" + ndxStr + "].constantAttenuation", 0.1f, 1.0f));
578 context.uniforms.push_back(gls::VarSpec("u_spotLight${NS}[" + ndxStr + "].linearAttenuation", 0.1f, 1.0f));
579 context.uniforms.push_back(gls::VarSpec("u_spotLight${NS}[" + ndxStr + "].quadraticAttenuation", 0.1f, 1.0f));
580 context.uniforms.push_back(gls::VarSpec("u_spotLight${NS}[" + ndxStr + "].spotExponent", 0.1f, 1.0f));
581 context.uniforms.push_back(gls::VarSpec("u_spotLight${NS}[" + ndxStr + "].spotCutoff", 0.1f, 1.0f));
582 }
583
584 context.uniforms.push_back(gls::VarSpec("u_spotLightCount${NS}", 4));
585
586 context.uniforms.push_back(gls::VarSpec("u_mvpMatrix${NS}", translationMat<4>(-0.2f), translationMat<4>(0.2f)));
587 context.uniforms.push_back(
588 gls::VarSpec("u_modelViewMatrix${NS}", translationMat<4>(-0.2f), translationMat<4>(0.2f)));
589 context.uniforms.push_back(gls::VarSpec("u_normalMatrix${NS}", translationMat<3>(-0.2f), translationMat<3>(0.2f)));
590 context.uniforms.push_back(
591 gls::VarSpec("u_texCoordMatrix0${NS}", translationMat<4>(-0.2f), translationMat<4>(0.2f)));
592
593 context.uniforms.push_back(gls::VarSpec("u_sampler0${NS}", 0));
594
595 context.textureSpecs.push_back(gls::TextureSpec(glu::TextureTestUtil::TEXTURETYPE_2D, 0, texWid, texHei, GL_RGBA,
596 GL_UNSIGNED_BYTE, GL_RGBA, true, GL_LINEAR, GL_LINEAR, GL_REPEAT,
597 GL_REPEAT, Vec4(0.0f), Vec4(1.0f)));
598
599 return context;
600 }
601
602 } // namespace LongStressTestUtil
603 } // namespace gls
604 } // namespace deqp
605