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 tcu::Vec2;
31 using tcu::Vec3;
32 using tcu::Vec4;
33 using tcu::Mat2;
34 using tcu::Mat3;
35 using tcu::Mat4;
36 using de::toString;
37 using std::map;
38 using std::string;
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)
83 : m_glslVersion (glslVersion)
84 {
85 DE_ASSERT(glslVersion == glu::GLSL_VERSION_100_ES || glslVersion == glu::GLSL_VERSION_300_ES);
86 }
87
generateBufferContext(const int numDummyAttributes) const88 gls::ProgramContext ProgramLibrary::generateBufferContext (const int numDummyAttributes) const
89 {
90 static const char* const vertexTemplate =
91 "${VTX_HEADER}"
92 "${VTX_IN} highp vec3 a_position;\n"
93 "${VTX_DUMMY_INPUTS}"
94 "${VTX_OUT} mediump vec4 v_color;\n"
95 "\n"
96 "void main (void)\n"
97 "{\n"
98 " gl_Position = vec4(a_position, 1.0);\n"
99 " v_color = ${VTX_COLOR_EXPRESSION};\n"
100 "}\n";
101
102 static const char* const fragmentTemplate =
103 "${FRAG_HEADER}"
104 "${FRAG_IN} mediump vec4 v_color;\n"
105 "\n"
106 "void main (void)\n"
107 "{\n"
108 " ${FRAG_COLOR} = v_color;\n"
109 "}\n";
110
111 map<string, string> firstLevelParams;
112
113 {
114 string vtxDummyInputs;
115 string vtxColorExpr;
116 for (int i = 0; i < numDummyAttributes; i++)
117 {
118 vtxDummyInputs += "${VTX_IN} mediump vec4 a_in" + toString(i) + ";\n";
119 vtxColorExpr += string() + (i > 0 ? " + " : "") + "a_in" + toString(i);
120 }
121
122 firstLevelParams["VTX_DUMMY_INPUTS"] = substitute(vtxDummyInputs);
123 firstLevelParams["VTX_COLOR_EXPRESSION"] = vtxColorExpr;
124 }
125
126 gls::ProgramContext context(substitute(vertexTemplate, firstLevelParams).c_str(), substitute(fragmentTemplate).c_str(), "a_position");
127
128 context.attributes.push_back(gls::VarSpec("a_position", Vec3(-0.1f), Vec3(0.1f)));
129
130 for (int i = 0; i < numDummyAttributes; i++)
131 context.attributes.push_back(gls::VarSpec("a_in" + de::toString(i), Vec4(0.0f), Vec4(1.0f / (float)numDummyAttributes)));
132
133 return context;
134 }
135
generateTextureContext(const int numTextures,const int texWid,const int texHei,const float positionFactor) const136 gls::ProgramContext ProgramLibrary::generateTextureContext (const int numTextures, const int texWid, const int texHei, const float positionFactor) const
137 {
138 static const char* const vertexTemplate =
139 "${VTX_HEADER}"
140 "${VTX_IN} highp vec3 a_position;\n"
141 "${VTX_IN} mediump vec2 a_texCoord;\n"
142 "${VTX_OUT} mediump vec2 v_texCoord;\n"
143 "uniform mediump mat4 u_posTrans;\n"
144 "\n"
145 "void main (void)\n"
146 "{\n"
147 " gl_Position = u_posTrans * vec4(a_position, 1.0);\n"
148 " v_texCoord = a_texCoord;\n"
149 "}\n";
150
151 static const char* const fragmentTemplate =
152 "${FRAG_HEADER}"
153 "${FRAG_IN} mediump vec2 v_texCoord;\n"
154 "uniform mediump sampler2D u_sampler;\n"
155 "\n"
156 "void main (void)\n"
157 "{\n"
158 " ${FRAG_COLOR} = ${TEXTURE_2D_FUNC}(u_sampler, v_texCoord);\n"
159 "}\n";
160
161 gls::ProgramContext context(substitute(vertexTemplate).c_str(), substitute(fragmentTemplate).c_str(), "a_position");
162
163 context.attributes.push_back(gls::VarSpec("a_position", Vec3(-positionFactor), Vec3(positionFactor)));
164 context.attributes.push_back(gls::VarSpec("a_texCoord", Vec2(0.0f), Vec2(1.0f)));
165
166 context.uniforms.push_back(gls::VarSpec("u_sampler", 0));
167 context.uniforms.push_back(gls::VarSpec("u_posTrans", translationMat<4>(positionFactor-1.0f), translationMat<4>(1.0f-positionFactor)));
168
169 for (int i = 0; i < numTextures; i++)
170 context.textureSpecs.push_back(gls::TextureSpec(gls::TextureTestUtil::TEXTURETYPE_2D, 0,
171 texWid, texHei, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA, true,
172 GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT,
173 Vec4(0.0f), Vec4(1.0f)));
174
175 return context;
176 }
177
generateBufferAndTextureContext(const int numTextures,const int texWid,const int texHei) const178 gls::ProgramContext ProgramLibrary::generateBufferAndTextureContext (const int numTextures, const int texWid, const int texHei) const
179 {
180 static const char* const vertexTemplate =
181 "${VTX_HEADER}"
182 "${VTX_IN} highp vec3 a_position;\n"
183 "${VTX_TEX_COORD_INPUTS}"
184 "${VTX_TEX_COORD_OUTPUTS}"
185 "\n"
186 "void main (void)\n"
187 "{\n"
188 " gl_Position = vec4(a_position, 1.0);\n"
189 "${VTX_TEX_COORD_WRITES}"
190 "}\n";
191
192 static const char* const fragmentTemplate =
193 "${FRAG_HEADER}"
194 "${FRAG_TEX_COORD_INPUTS}"
195 "${FRAG_SAMPLERS}"
196 "\n"
197 "void main (void)\n"
198 "{\n"
199 " ${FRAG_COLOR} =${FRAG_COLOR_EXPRESSION};\n"
200 "}\n";
201
202 map<string, string> firstLevelParams;
203
204 {
205 string vtxTexCoordInputs;
206 string vtxTexCoordOutputs;
207 string vtxTexCoordWrites;
208 string fragTexCoordInputs;
209 string fragSamplers;
210 string fragColorExpression;
211
212 for (int i = 0; i < numTextures; i++)
213 {
214 vtxTexCoordInputs += "${VTX_IN} mediump vec2 a_texCoord" + toString(i) + ";\n";
215 vtxTexCoordOutputs += "${VTX_OUT} mediump vec2 v_texCoord" + toString(i) + ";\n";
216 vtxTexCoordWrites += "\tv_texCoord" + toString(i) + " = " + "a_texCoord" + toString(i) + ";\n";
217 fragTexCoordInputs += "${FRAG_IN} mediump vec2 v_texCoord" + toString(i) + ";\n";
218 fragSamplers += "uniform mediump sampler2D u_sampler" + toString(i) + ";\n";
219 fragColorExpression += string() + (i > 0 ? " +" : "") + "\n\t\t${TEXTURE_2D_FUNC}(u_sampler" + toString(i) + ", v_texCoord" + toString(i) + ")";
220 }
221
222 firstLevelParams["VTX_TEX_COORD_INPUTS"] = substitute(vtxTexCoordInputs);
223 firstLevelParams["VTX_TEX_COORD_OUTPUTS"] = substitute(vtxTexCoordOutputs);
224 firstLevelParams["VTX_TEX_COORD_WRITES"] = vtxTexCoordWrites;
225 firstLevelParams["FRAG_TEX_COORD_INPUTS"] = substitute(fragTexCoordInputs);
226 firstLevelParams["FRAG_SAMPLERS"] = fragSamplers;
227 firstLevelParams["FRAG_COLOR_EXPRESSION"] = substitute(fragColorExpression);
228 }
229
230 gls::ProgramContext context(substitute(vertexTemplate, firstLevelParams).c_str(), substitute(fragmentTemplate, firstLevelParams).c_str(), "a_position");
231
232 context.attributes.push_back(gls::VarSpec("a_position", Vec3(-0.1f), Vec3(0.1f)));
233
234 for (int i = 0; i < numTextures; i++)
235 {
236 context.attributes.push_back(gls::VarSpec("a_texCoord" + de::toString(i), Vec2(0.0f), Vec2(1.0f)));
237 context.uniforms.push_back(gls::VarSpec("u_sampler" + de::toString(i), i));
238 context.textureSpecs.push_back(gls::TextureSpec(gls::TextureTestUtil::TEXTURETYPE_2D, i,
239 texWid, texHei, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA, true,
240 GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT,
241 Vec4(0.0f), Vec4(1.0f / (float)numTextures)));
242 }
243
244 return context;
245 }
246
generateFragmentPointLightContext(const int texWid,const int texHei) const247 gls::ProgramContext ProgramLibrary::generateFragmentPointLightContext (const int texWid, const int texHei) const
248 {
249 static const char* const vertexTemplate =
250 "${VTX_HEADER}"
251 "struct Material\n"
252 "{\n"
253 " mediump vec3 ambientColor;\n"
254 " mediump vec4 diffuseColor;\n"
255 " mediump vec3 emissiveColor;\n"
256 " mediump vec3 specularColor;\n"
257 " mediump float shininess;\n"
258 "};\n"
259 "\n"
260 "struct Light\n"
261 "{\n"
262 " mediump vec3 color;\n"
263 " mediump vec4 position;\n"
264 " mediump vec3 direction;\n"
265 " mediump float constantAttenuation;\n"
266 " mediump float linearAttenuation;\n"
267 " mediump float quadraticAttenuation;\n"
268 "};\n"
269 "\n"
270 "${VTX_IN} highp vec4 a_position${NS};\n"
271 "${VTX_IN} mediump vec3 a_normal${NS};\n"
272 "${VTX_IN} mediump vec3 a_color${NS};\n"
273 "${VTX_IN} mediump vec4 a_texCoord0${NS};\n"
274 "\n"
275 "uniform Material u_material${NS};\n"
276 "uniform Light u_light${NS}[1];\n"
277 "uniform highp mat4 u_mvpMatrix${NS};\n"
278 "uniform mediump mat4 u_modelViewMatrix${NS};\n"
279 "uniform mediump mat3 u_normalMatrix${NS};\n"
280 "uniform mediump mat4 u_texCoordMatrix0${NS};\n"
281 "\n"
282 "${VTX_OUT} mediump vec4 v_baseColor${NS};\n"
283 "${VTX_OUT} mediump vec2 v_texCoord0${NS};\n"
284 "\n"
285 "${VTX_OUT} mediump vec3 v_eyeNormal${NS};\n"
286 "${VTX_OUT} mediump vec3 v_directionToLight${NS}[1];\n"
287 "${VTX_OUT} mediump float v_distanceToLight${NS}[1];\n"
288 "\n"
289 "vec3 direction (vec4 from, vec4 to)\n"
290 "{\n"
291 " return vec3(to.xyz * from.w - from.xyz * to.w);\n"
292 "}\n"
293 "\n"
294 "void main (void)\n"
295 "{\n"
296 " gl_Position = u_mvpMatrix${NS} * a_position${NS};\n"
297 " v_texCoord0${NS} = (u_texCoordMatrix0${NS} * a_texCoord0${NS}).xy;\n"
298 "\n"
299 " mediump vec4 eyePosition = u_modelViewMatrix${NS} * a_position${NS};\n"
300 " mediump vec3 eyeNormal = normalize(u_normalMatrix${NS} * a_normal${NS});\n"
301 "\n"
302 " vec4 color = vec4(0.0, 0.0, 0.0, 1.0);\n"
303 " color.rgb += u_material${NS}.emissiveColor;\n"
304 "\n"
305 " color.a *= u_material${NS}.diffuseColor.a;\n"
306 "\n"
307 " v_baseColor${NS} = color;\n"
308 "\n"
309 " v_distanceToLight${NS}[0] = distance(eyePosition, u_light${NS}[0].position);\n"
310 " v_directionToLight${NS}[0] = normalize(direction(eyePosition, u_light${NS}[0].position));\n"
311 "\n"
312 " v_eyeNormal${NS} = eyeNormal;\n"
313 "}\n";
314
315 static const char* const fragmentTemplate =
316 "${FRAG_HEADER}"
317 "struct Light\n"
318 "{\n"
319 " mediump vec3 color;\n"
320 " mediump vec4 position;\n"
321 " mediump vec3 direction;\n"
322 " mediump float constantAttenuation;\n"
323 " mediump float linearAttenuation;\n"
324 " mediump float quadraticAttenuation;\n"
325 "};\n"
326 "\n"
327 "struct Material\n"
328 "{\n"
329 " mediump vec3 ambientColor;\n"
330 " mediump vec4 diffuseColor;\n"
331 " mediump vec3 emissiveColor;\n"
332 " mediump vec3 specularColor;\n"
333 " mediump float shininess;\n"
334 "};\n"
335 "\n"
336 "uniform sampler2D u_sampler0${NS};\n"
337 "uniform Light u_light${NS}[1];\n"
338 "uniform Material u_material${NS};\n"
339 "\n"
340 "${FRAG_IN} mediump vec4 v_baseColor${NS};\n"
341 "${FRAG_IN} mediump vec2 v_texCoord0${NS};\n"
342 "\n"
343 "${FRAG_IN} mediump vec3 v_eyeNormal${NS};\n"
344 "${FRAG_IN} mediump vec3 v_directionToLight${NS}[1];\n"
345 "${FRAG_IN} mediump float v_distanceToLight${NS}[1];\n"
346 "\n"
347 "mediump vec3 computeLighting (Light light, mediump vec3 directionToLight, mediump vec3 vertexEyeNormal)\n"
348 "{\n"
349 " mediump float normalDotDirection = max(dot(vertexEyeNormal, directionToLight), 0.0);\n"
350 " mediump vec3 color = normalDotDirection * u_material${NS}.diffuseColor.rgb * light.color;\n"
351 "\n"
352 " if (normalDotDirection != 0.0)\n"
353 " {\n"
354 " mediump vec3 h = normalize(directionToLight + vec3(0.0, 0.0, 1.0));\n"
355 " color.rgb += pow(max(dot(vertexEyeNormal, h), 0.0), u_material${NS}.shininess) * 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]) * computeLighting(u_light${NS}[0], normalize(v_directionToLight${NS}[0]), eyeNormal);\n"
376 "\n"
377 " color *= ${TEXTURE_2D_FUNC}(u_sampler0${NS}, v_texCoord0${NS});\n"
378 "\n"
379 " ${FRAG_COLOR} = color;\n"
380 "}\n";
381
382 gls::ProgramContext context(substitute(vertexTemplate).c_str(), substitute(fragmentTemplate).c_str(), "a_position${NS}");
383
384 context.attributes.push_back(gls::VarSpec("a_position${NS}", Vec4(-1.0f), Vec4(1.0f)));
385 context.attributes.push_back(gls::VarSpec("a_normal${NS}", Vec3(-1.0f), Vec3(1.0f)));
386 context.attributes.push_back(gls::VarSpec("a_texCoord0${NS}", Vec4(-1.0f), Vec4(1.0f)));
387
388 context.uniforms.push_back(gls::VarSpec("u_material${NS}.ambientColor", Vec3(0.0f), Vec3(1.0f)));
389 context.uniforms.push_back(gls::VarSpec("u_material${NS}.diffuseColor", Vec4(0.0f), Vec4(1.0f)));
390 context.uniforms.push_back(gls::VarSpec("u_material${NS}.emissiveColor", Vec3(0.0f), Vec3(1.0f)));
391 context.uniforms.push_back(gls::VarSpec("u_material${NS}.specularColor", Vec3(0.0f), Vec3(1.0f)));
392 context.uniforms.push_back(gls::VarSpec("u_material${NS}.shininess", 0.0f, 1.0f));
393
394 context.uniforms.push_back(gls::VarSpec("u_light${NS}[0].color", Vec3(0.0f), Vec3(1.0f)));
395 context.uniforms.push_back(gls::VarSpec("u_light${NS}[0].position", Vec4(-1.0f), Vec4(1.0f)));
396 context.uniforms.push_back(gls::VarSpec("u_light${NS}[0].direction", Vec3(-1.0f), Vec3(1.0f)));
397 context.uniforms.push_back(gls::VarSpec("u_light${NS}[0].constantAttenuation", 0.1f, 1.0f));
398 context.uniforms.push_back(gls::VarSpec("u_light${NS}[0].linearAttenuation", 0.1f, 1.0f));
399 context.uniforms.push_back(gls::VarSpec("u_light${NS}[0].quadraticAttenuation", 0.1f, 1.0f));
400
401 context.uniforms.push_back(gls::VarSpec("u_mvpMatrix${NS}", translationMat<4>(-0.2f), translationMat<4>(0.2f)));
402 context.uniforms.push_back(gls::VarSpec("u_modelViewMatrix${NS}", translationMat<4>(-0.2f), translationMat<4>(0.2f)));
403 context.uniforms.push_back(gls::VarSpec("u_normalMatrix${NS}", translationMat<3>(-0.2f), translationMat<3>(0.2f)));
404 context.uniforms.push_back(gls::VarSpec("u_texCoordMatrix0${NS}", translationMat<4>(-0.2f), translationMat<4>(0.2f)));
405
406 context.uniforms.push_back(gls::VarSpec("u_sampler0${NS}", 0));
407
408 context.textureSpecs.push_back(gls::TextureSpec(gls::TextureTestUtil::TEXTURETYPE_2D, 0,
409 texWid, texHei, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA,
410 true, GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT,
411 Vec4(0.0f), Vec4(1.0f)));
412
413 return context;
414 }
415
generateVertexUniformLoopLightContext(const int texWid,const int texHei) const416 gls::ProgramContext ProgramLibrary::generateVertexUniformLoopLightContext (const int texWid, const int texHei) const
417 {
418 static const char* const vertexTemplate =
419 "${VTX_HEADER}"
420 "struct Material {\n"
421 " mediump vec3 ambientColor;\n"
422 " mediump vec4 diffuseColor;\n"
423 " mediump vec3 emissiveColor;\n"
424 " mediump vec3 specularColor;\n"
425 " mediump float shininess;\n"
426 "};\n"
427 "struct Light {\n"
428 " mediump vec3 color;\n"
429 " mediump vec4 position;\n"
430 " mediump vec3 direction;\n"
431 " mediump float constantAttenuation;\n"
432 " mediump float linearAttenuation;\n"
433 " mediump float quadraticAttenuation;\n"
434 " mediump float spotExponent;\n"
435 " mediump float spotCutoff;\n"
436 "};\n"
437 "${VTX_IN} highp vec4 a_position${NS};\n"
438 "${VTX_IN} mediump vec3 a_normal${NS};\n"
439 "${VTX_IN} mediump vec4 a_texCoord0${NS};\n"
440 "uniform Material u_material${NS};\n"
441 "uniform Light u_directionalLight${NS}[1];\n"
442 "uniform mediump int u_directionalLightCount${NS};\n"
443 "uniform Light u_spotLight${NS}[4];\n"
444 "uniform mediump int u_spotLightCount${NS};\n"
445 "uniform highp mat4 u_mvpMatrix${NS};\n"
446 "uniform highp mat4 u_modelViewMatrix${NS};\n"
447 "uniform mediump mat3 u_normalMatrix${NS};\n"
448 "uniform mediump mat4 u_texCoordMatrix0${NS};\n"
449 "${VTX_OUT} mediump vec4 v_color${NS};\n"
450 "${VTX_OUT} mediump vec2 v_texCoord0${NS};\n"
451 "mediump vec3 direction (mediump vec4 from, mediump vec4 to)\n"
452 "{\n"
453 " return vec3(to.xyz * from.w - from.xyz * to.w);\n"
454 "}\n"
455 "\n"
456 "mediump vec3 computeLighting (\n"
457 " mediump vec3 directionToLight,\n"
458 " mediump vec3 halfVector,\n"
459 " mediump vec3 normal,\n"
460 " mediump vec3 lightColor,\n"
461 " mediump vec3 diffuseColor,\n"
462 " mediump vec3 specularColor,\n"
463 " mediump float shininess)\n"
464 "{\n"
465 " mediump float normalDotDirection = max(dot(normal, directionToLight), 0.0);\n"
466 " mediump vec3 color = normalDotDirection * diffuseColor * lightColor;\n"
467 "\n"
468 " if (normalDotDirection != 0.0)\n"
469 " color += pow(max(dot(normal, halfVector), 0.0), shininess) * specularColor * lightColor;\n"
470 "\n"
471 " return color;\n"
472 "}\n"
473 "\n"
474 "mediump float computeDistanceAttenuation (mediump float distToLight, mediump float constAtt, mediump float linearAtt, mediump float quadraticAtt)\n"
475 "{\n"
476 " return 1.0 / (constAtt + linearAtt * distToLight + quadraticAtt * distToLight * distToLight);\n"
477 "}\n"
478 "\n"
479 "mediump float computeSpotAttenuation (\n"
480 " mediump vec3 directionToLight,\n"
481 " mediump vec3 lightDir,\n"
482 " mediump float spotExponent,\n"
483 " mediump float spotCutoff)\n"
484 "{\n"
485 " mediump float spotEffect = dot(lightDir, normalize(-directionToLight));\n"
486 "\n"
487 " if (spotEffect < spotCutoff)\n"
488 " spotEffect = 0.0;\n"
489 "\n"
490 " spotEffect = pow(spotEffect, spotExponent);\n"
491 " return spotEffect;\n"
492 "}\n"
493 "\n"
494 "void main (void)\n"
495 "{\n"
496 " highp vec4 position = a_position${NS};\n"
497 " highp vec3 normal = a_normal${NS};\n"
498 " gl_Position = u_mvpMatrix${NS} * position;\n"
499 " v_texCoord0${NS} = (u_texCoordMatrix0${NS} * a_texCoord0${NS}).xy;\n"
500 " mediump vec4 color = vec4(u_material${NS}.emissiveColor, u_material${NS}.diffuseColor.a);\n"
501 "\n"
502 " highp vec4 eyePosition = u_modelViewMatrix${NS} * position;\n"
503 " mediump vec3 eyeNormal = normalize(u_normalMatrix${NS} * normal);\n"
504 " for (int i = 0; i < u_directionalLightCount${NS}; i++)\n"
505 " {\n"
506 " mediump vec3 directionToLight = -u_directionalLight${NS}[i].direction;\n"
507 " mediump vec3 halfVector = normalize(directionToLight + vec3(0.0, 0.0, 1.0));\n"
508 " color.rgb += computeLighting(directionToLight, halfVector, eyeNormal, u_directionalLight${NS}[i].color, u_material${NS}.diffuseColor.rgb, u_material${NS}.specularColor, u_material${NS}.shininess);\n"
509 " }\n"
510 "\n"
511 " for (int i = 0; i < u_spotLightCount${NS}; i++)\n"
512 " {\n"
513 " mediump float distanceToLight = distance(eyePosition, u_spotLight${NS}[i].position);\n"
514 " mediump vec3 directionToLight = normalize(direction(eyePosition, u_spotLight${NS}[i].position));\n"
515 " mediump vec3 halfVector = normalize(directionToLight + vec3(0.0, 0.0, 1.0));\n"
516 " color.rgb += computeLighting(directionToLight, halfVector, eyeNormal, u_spotLight${NS}[i].color, u_material${NS}.diffuseColor.rgb, u_material${NS}.specularColor, u_material${NS}.shininess) * computeDistanceAttenuation(distanceToLight, u_spotLight${NS}[i].constantAttenuation, u_spotLight${NS}[i].linearAttenuation, u_spotLight${NS}[i].quadraticAttenuation) * computeSpotAttenuation(directionToLight, u_spotLight${NS}[i].direction, u_spotLight${NS}[i].spotExponent, u_spotLight${NS}[i].spotCutoff);\n"
517 " }\n"
518 "\n"
519 "\n"
520 " v_color${NS} = color;\n"
521 "}\n";
522
523 static const char* const fragmentTemplate =
524 "${FRAG_HEADER}"
525 "uniform sampler2D u_sampler0${NS};\n"
526 "${FRAG_IN} mediump vec4 v_color${NS};\n"
527 "${FRAG_IN} mediump vec2 v_texCoord0${NS};\n"
528 "void main (void)\n"
529 "{\n"
530 " mediump vec2 texCoord0 = v_texCoord0${NS};\n"
531 " mediump vec4 color = v_color${NS};\n"
532 " color *= ${TEXTURE_2D_FUNC}(u_sampler0${NS}, texCoord0);\n"
533 " ${FRAG_COLOR} = color;\n"
534 "}\n";
535
536 gls::ProgramContext context(substitute(vertexTemplate).c_str(), substitute(fragmentTemplate).c_str(), "a_position${NS}");
537
538 context.attributes.push_back (gls::VarSpec("a_position${NS}", Vec4(-1.0f), Vec4(1.0f)));
539 context.attributes.push_back (gls::VarSpec("a_normal${NS}", Vec3(-1.0f), Vec3(1.0f)));
540 context.attributes.push_back (gls::VarSpec("a_texCoord0${NS}", Vec4(-1.0f), Vec4(1.0f)));
541
542 context.uniforms.push_back (gls::VarSpec("u_material${NS}.ambientColor", Vec3(0.0f), Vec3(1.0f)));
543 context.uniforms.push_back (gls::VarSpec("u_material${NS}.diffuseColor", Vec4(0.0f), Vec4(1.0f)));
544 context.uniforms.push_back (gls::VarSpec("u_material${NS}.emissiveColor", Vec3(0.0f), Vec3(1.0f)));
545 context.uniforms.push_back (gls::VarSpec("u_material${NS}.specularColor", Vec3(0.0f), Vec3(1.0f)));
546 context.uniforms.push_back (gls::VarSpec("u_material${NS}.shininess", 0.0f, 1.0f));
547
548 context.uniforms.push_back (gls::VarSpec("u_directionalLight${NS}[0].color", Vec3(0.0f), Vec3(1.0f)));
549 context.uniforms.push_back (gls::VarSpec("u_directionalLight${NS}[0].position", Vec4(-1.0f), Vec4(1.0f)));
550 context.uniforms.push_back (gls::VarSpec("u_directionalLight${NS}[0].direction", Vec3(-1.0f), Vec3(1.0f)));
551 context.uniforms.push_back (gls::VarSpec("u_directionalLight${NS}[0].constantAttenuation", 0.1f, 1.0f));
552 context.uniforms.push_back (gls::VarSpec("u_directionalLight${NS}[0].linearAttenuation", 0.1f, 1.0f));
553 context.uniforms.push_back (gls::VarSpec("u_directionalLight${NS}[0].quadraticAttenuation", 0.1f, 1.0f));
554 context.uniforms.push_back (gls::VarSpec("u_directionalLight${NS}[0].spotExponent", 0.1f, 1.0f));
555 context.uniforms.push_back (gls::VarSpec("u_directionalLight${NS}[0].spotCutoff", 0.1f, 1.0f));
556
557 context.uniforms.push_back (gls::VarSpec("u_directionalLightCount${NS}", 1));
558
559 for (int i = 0; i < 4; i++)
560 {
561 const std::string ndxStr = de::toString(i);
562
563 context.uniforms.push_back(gls::VarSpec("u_spotLight${NS}["+ndxStr+"].color", Vec3(0.0f), Vec3(1.0f)));
564 context.uniforms.push_back(gls::VarSpec("u_spotLight${NS}["+ndxStr+"].position", Vec4(-1.0f), Vec4(1.0f)));
565 context.uniforms.push_back(gls::VarSpec("u_spotLight${NS}["+ndxStr+"].direction", Vec3(-1.0f), Vec3(1.0f)));
566 context.uniforms.push_back(gls::VarSpec("u_spotLight${NS}["+ndxStr+"].constantAttenuation", 0.1f, 1.0f));
567 context.uniforms.push_back(gls::VarSpec("u_spotLight${NS}["+ndxStr+"].linearAttenuation", 0.1f, 1.0f));
568 context.uniforms.push_back(gls::VarSpec("u_spotLight${NS}["+ndxStr+"].quadraticAttenuation", 0.1f, 1.0f));
569 context.uniforms.push_back(gls::VarSpec("u_spotLight${NS}["+ndxStr+"].spotExponent", 0.1f, 1.0f));
570 context.uniforms.push_back(gls::VarSpec("u_spotLight${NS}["+ndxStr+"].spotCutoff", 0.1f, 1.0f));
571 }
572
573 context.uniforms.push_back (gls::VarSpec("u_spotLightCount${NS}", 4));
574
575 context.uniforms.push_back (gls::VarSpec("u_mvpMatrix${NS}", translationMat<4>(-0.2f), translationMat<4>(0.2f)));
576 context.uniforms.push_back (gls::VarSpec("u_modelViewMatrix${NS}", translationMat<4>(-0.2f), translationMat<4>(0.2f)));
577 context.uniforms.push_back (gls::VarSpec("u_normalMatrix${NS}", translationMat<3>(-0.2f), translationMat<3>(0.2f)));
578 context.uniforms.push_back (gls::VarSpec("u_texCoordMatrix0${NS}", translationMat<4>(-0.2f), translationMat<4>(0.2f)));
579
580 context.uniforms.push_back (gls::VarSpec("u_sampler0${NS}", 0));
581
582 context.textureSpecs.push_back (gls::TextureSpec(gls::TextureTestUtil::TEXTURETYPE_2D, 0,
583 texWid, texHei, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA,
584 true, GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT,
585 Vec4(0.0f), Vec4(1.0f)));
586
587 return context;
588 }
589
590 } // StressTestUtil
591 } // gls
592 } // deqp
593