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:
LightAmountCase(Context & context,const char * name,int numDirectionalLights,int numOmniLights,int numSpotLights)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
iterate(void)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
LightAmountTest(Context & context)186 LightAmountTest::LightAmountTest (Context& context) : TestCaseGroup(context, "light_amount", "Light Amount Stress Tests")
187 {
188 }
189
~LightAmountTest(void)190 LightAmountTest::~LightAmountTest (void)
191 {
192 }
193
init(void)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