1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES 2.0 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 Light amount test. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "es2fLightAmountTest.hpp" 25 #include "tcuStringTemplate.hpp" 26 #include "gluDefs.hpp" 27 #include "gluShaderProgram.hpp" 28 #include "tcuTestLog.hpp" 29 #include "deStringUtil.hpp" 30 #include "deInt32.h" 31 #include "deRandom.h" 32 33 #include <stdio.h> 34 #include <vector> 35 36 #include "glw.h" 37 38 using namespace std; 39 40 namespace deqp 41 { 42 namespace gles2 43 { 44 namespace Functional 45 { 46 47 const char* s_noLightsVertexShader = 48 "uniform mat4 u_modelviewMatrix;\n" 49 "uniform mat4 u_modelviewProjectionMatrix;\n" 50 "uniform mat3 u_normalMatrix;\n" 51 "\n" 52 "attribute vec4 a_position;\n" 53 "attribute vec3 a_normal;\n" 54 "\n" 55 "varying vec3 v_color;\n" 56 "\n" 57 "void main()\n" 58 "{\n" 59 " v_color = vec3(0.0);\n" 60 " gl_Position = u_modelviewProjectionMatrix * a_position;\n" 61 "}\n" 62 ; 63 64 const char* s_vertexShaderTemplate = 65 "struct Light\n" 66 "{\n" 67 " vec3 position;\n" 68 " vec3 diffuse;\n" 69 " vec3 specular;\n" 70 " vec3 attenuation;\n" 71 "};\n" 72 "uniform Light u_lights[${NUM_DIR_LIGHTS} + ${NUM_OMNI_LIGHTS}];\n" 73 "uniform mat4 u_modelviewMatrix;\n" 74 "uniform mat4 u_modelviewProjectionMatrix;\n" 75 "uniform mat3 u_normalMatrix;\n" 76 "\n" 77 "attribute vec4 a_position;\n" 78 "attribute vec3 a_normal;\n" 79 "\n" 80 "varying vec3 v_color;\n" 81 "\n" 82 "float computeAttenuation(vec3 dirToLight, vec3 attenuation)\n" 83 "{\n" 84 " float dist = length(dirToLight);\n" 85 " return 1.0 / (attenuation.x + attenuation.y*dist + attenuation.z*dist*dist);\n" 86 "}\n" 87 "\n" 88 "vec3 computeDirLight(int ndx, vec3 position, vec3 normal)\n" 89 "{\n" 90 " Light light = u_lights[ndx];\n" 91 " float cosAngle = dot(light.position, normal);\n" 92 " return cosAngle * light.diffuse;\n" 93 "}\n" 94 "\n" 95 "vec3 computeOmniLight(int ndx, vec3 position, vec3 normal)\n" 96 "{\n" 97 " Light light = u_lights[ndx];\n" 98 " vec3 dirToLight = light.position - position;\n" 99 " float cosAngle = dot(normalize(dirToLight), normal);\n" 100 " float atten = computeAttenuation(dirToLight, light.attenuation);\n" 101 " return atten * cosAngle * light.diffuse;\n" 102 "}\n" 103 "\n" 104 "void main()\n" 105 "{\n" 106 " vec3 lightSpacePos = vec3(u_modelviewMatrix * a_position);\n" 107 " vec3 lightNormal = normalize(u_normalMatrix * a_normal);\n" 108 " vec3 color = vec3(0.0);\n" 109 " for (int i = 0; i < ${NUM_DIR_LIGHTS}; i++)\n" 110 " color += computeDirLight(i, lightSpacePos, lightNormal);\n" 111 " for (int i = 0; i < ${NUM_OMNI_LIGHTS}; i++)\n" 112 " color += computeOmniLight(${NUM_DIR_LIGHTS}+i, lightSpacePos, lightNormal);\n" 113 " v_color = color;\n" 114 " gl_Position = u_modelviewProjectionMatrix * a_position;\n" 115 "}\n" 116 ; 117 118 const char* s_fragmentShaderTemplate = 119 "varying highp vec3 v_color;\n" 120 "\n" 121 "void main()\n" 122 "{\n" 123 " gl_FragColor = vec4(v_color, 1.0);\n" 124 "}\n" 125 ; 126 127 class LightAmountCase : public TestCase 128 { 129 public: 130 LightAmountCase(Context& context, const char* name, int numDirectionalLights, int numOmniLights, int numSpotLights) 131 : TestCase(context, name, name) 132 , m_numDirectionalLights (numDirectionalLights) 133 , m_numOmniLights (numOmniLights) 134 , m_numSpotLights (numSpotLights) 135 { 136 } 137 138 virtual IterateResult iterate (void); 139 140 private: 141 int m_numDirectionalLights; 142 int m_numOmniLights; 143 int m_numSpotLights; 144 }; 145 146 TestCase::IterateResult LightAmountCase::iterate (void) 147 { 148 GLU_CHECK_MSG("LightAmountTest::iterate() begin"); 149 150 string vertexShaderSource; 151 string fragmentShaderSource; 152 153 // Fill in shader template parameters. 154 { 155 bool hasAnyLights = ((m_numDirectionalLights + m_numOmniLights + m_numSpotLights) != 0); 156 157 tcu::StringTemplate vertexTemplate(hasAnyLights ? s_vertexShaderTemplate : s_noLightsVertexShader); 158 tcu::StringTemplate fragmentTemplate(s_fragmentShaderTemplate); 159 160 map<string, string> params; 161 params.insert(pair<string, string>("NUM_DIR_LIGHTS", de::toString(m_numDirectionalLights))); 162 params.insert(pair<string, string>("NUM_OMNI_LIGHTS", de::toString(m_numOmniLights))); 163 params.insert(pair<string, string>("NUM_SPOT_LIGHTS", de::toString(m_numSpotLights))); 164 165 vertexShaderSource = vertexTemplate.specialize(params); 166 fragmentShaderSource = fragmentTemplate.specialize(params); 167 } 168 169 // Create shader and program objects. 170 glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource)); 171 m_testCtx.getLog() << program; 172 173 // Draw something? Check results? 174 glUseProgram(program.getProgram()); 175 176 bool testOk = program.isOk(); 177 178 GLU_CHECK_MSG("LightAmountTest::iterate() end"); 179 180 m_testCtx.setTestResult(testOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, testOk ? "Pass" : "Fail"); 181 return TestCase::STOP; 182 } 183 184 // 185 186 LightAmountTest::LightAmountTest (Context& context) : TestCaseGroup(context, "light_amount", "Light Amount Stress Tests") 187 { 188 } 189 190 LightAmountTest::~LightAmountTest (void) 191 { 192 } 193 194 void LightAmountTest::init (void) 195 { 196 // name dir, omni, spot 197 addChild(new LightAmountCase(m_context, "none", 0, 0, 0 )); 198 addChild(new LightAmountCase(m_context, "1dir", 1, 0, 0 )); 199 addChild(new LightAmountCase(m_context, "2dir", 2, 0, 0 )); 200 addChild(new LightAmountCase(m_context, "4dir", 4, 0, 0 )); 201 addChild(new LightAmountCase(m_context, "6dir", 6, 0, 0 )); 202 addChild(new LightAmountCase(m_context, "8dir", 8, 0, 0 )); 203 addChild(new LightAmountCase(m_context, "10dir", 10, 0, 0 )); 204 addChild(new LightAmountCase(m_context, "12dir", 12, 0, 0 )); 205 addChild(new LightAmountCase(m_context, "14dir", 14, 0, 0 )); 206 addChild(new LightAmountCase(m_context, "16dir", 16, 0, 0 )); 207 addChild(new LightAmountCase(m_context, "1omni", 0, 1, 0 )); 208 addChild(new LightAmountCase(m_context, "2omni", 0, 2, 0 )); 209 addChild(new LightAmountCase(m_context, "4omni", 0, 4, 0 )); 210 addChild(new LightAmountCase(m_context, "6omni", 0, 6, 0 )); 211 addChild(new LightAmountCase(m_context, "8omni", 0, 8, 0 )); 212 addChild(new LightAmountCase(m_context, "10omni", 0, 10, 0 )); 213 addChild(new LightAmountCase(m_context, "12omni", 0, 12, 0 )); 214 addChild(new LightAmountCase(m_context, "14omni", 0, 14, 0 )); 215 addChild(new LightAmountCase(m_context, "16omni", 0, 16, 0 )); 216 // addChild(new LightAmountCase(m_context, "1spot", 0, 0, 1 )); 217 // addChild(new LightAmountCase(m_context, "2spot", 0, 0, 2 )); 218 // addChild(new LightAmountCase(m_context, "4spot", 0, 0, 4 )); 219 // addChild(new LightAmountCase(m_context, "6spot", 0, 0, 6 )); 220 // addChild(new LightAmountCase(m_context, "8spot", 0, 0, 8 )); 221 // addChild(new LightAmountCase(m_context, "1dir_1omni", 1, 1, 0 )); 222 // addChild(new LightAmountCase(m_context, "2dir_2omni", 2, 2, 0 )); 223 // addChild(new LightAmountCase(m_context, "4dir_4omni", 4, 4, 0 )); 224 // addChild(new LightAmountCase(m_context, "1dir_1spot", 1, 0, 1 )); 225 // addChild(new LightAmountCase(m_context, "2dir_2spot", 2, 0, 2 )); 226 // addChild(new LightAmountCase(m_context, "4dir_4spot", 4, 0, 4 )); 227 // addChild(new LightAmountCase(m_context, "1omni_1spot", 0, 1, 1 )); 228 // addChild(new LightAmountCase(m_context, "2omni_2spot", 0, 2, 2 )); 229 // addChild(new LightAmountCase(m_context, "4omni_4spot", 0, 4, 4 )); 230 // addChild(new LightAmountCase(m_context, "1dir_1omni_1spot", 1, 1, 1 )); 231 // addChild(new LightAmountCase(m_context, "2dir_2omni_2spot", 2, 2, 2 )); 232 // addChild(new LightAmountCase(m_context, "4dir_2omni_2spot", 4, 2, 2 )); 233 // addChild(new LightAmountCase(m_context, "2dir_4omni_2spot", 2, 4, 2 )); 234 // addChild(new LightAmountCase(m_context, "2dir_2omni_4spot", 2, 2, 4 )); 235 // addChild(new LightAmountCase(m_context, "4dir_4omni_4spot", 4, 4, 4 )); 236 } 237 238 } // Functional 239 } // gles2 240 } // deqp 241