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> 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. 58 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 77 string ProgramLibrary::substitute (const std::string& templ) const 78 { 79 return substitute(templ, map<string, string>()); 80 } 81 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 88 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 136 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 178 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 247 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 416 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