Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(128)

Side by Side Diff: chrome/test/data/gpu/webgl_teapot/teapot_files/demo.js

Issue 4723006: Add test fixture for GPU browser tests which do image comparisons.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2009 The Chromium Authors. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 var gl = null;
32 var g_width = 0;
33 var g_height = 0;
34 var g_bumpTexture = null;
35 var g_envTexture = null;
36 var g_programObject = null;
37 var g_vbo = null;
38 var g_elementVbo = null;
39 var g_normalsOffset = 0;
40 var g_tangentsOffset = 0;
41 var g_binormalsOffset = 0;
42 var g_texCoordsOffset = 0;
43 var g_numElements = 0;
44
45 // Uniform variables
46 var g_worldLoc = 0;
47 var g_worldInverseTransposeLoc = 0;
48 var g_worldViewProjLoc = 0;
49 var g_viewInverseLoc = 0;
50 var g_normalSamplerLoc = 0;
51 var g_envSamplerLoc = 0;
52
53 var g_pendingTextureLoads = 0;
54
55 // The "model" matrix is the "world" matrix in Standard Annotations
56 // and Semantics
57 var model = new Matrix4x4();
58 var view = new Matrix4x4();
59 var projection = new Matrix4x4();
60
61 var controller = null;
62
63 function main() {
64 var c = document.getElementById("c");
65 gl = getWebGLContext(c);
66 if (!gl)
67 return;
68 g_width = c.width;
69 g_height = c.height;
70 controller = new CameraController(c);
71 // Try the following (and uncomment the "pointer-events: none;" in
72 // the index.html) to try the more precise hit detection
73 // controller = new CameraController(document.getElementById("body"), c, gl );
74 controller.onchange = function(xRot, yRot) {
75 draw();
76 };
77 init();
78 draw();
79 }
80
81 function output(str) {
82 document.body.appendChild(document.createTextNode(str));
83 document.body.appendChild(document.createElement("br"));
84 }
85
86 function checkGLError() {
87 var error = gl.getError();
88 if (error != gl.NO_ERROR) {
89 var str = "GL Error: " + error;
90 output(str);
91 throw str;
92 }
93 }
94
95 function init() {
96 gl.enable(gl.DEPTH_TEST);
97 // Can use this to make the background opaque
98 // gl.clearColor(0.3, 0.2, 0.2, 1.);
99 gl.clearColor(0.0, 0.0, 0.0, 0.0);
100 gl.viewport(0, 0, g_width, g_height);
101 initTeapot();
102 initShaders();
103 g_bumpTexture = loadTexture("bump.jpg");
104 g_envTexture = loadCubeMap("skybox", "jpg");
105 }
106
107 function initTeapot() {
108 g_vbo = gl.createBuffer();
109 gl.bindBuffer(gl.ARRAY_BUFFER, g_vbo);
110 gl.bufferData(gl.ARRAY_BUFFER,
111 teapotPositions.byteLength +
112 teapotNormals.byteLength +
113 teapotTangents.byteLength +
114 teapotBinormals.byteLength +
115 teapotTexCoords.byteLength,
116 gl.STATIC_DRAW);
117 g_normalsOffset = teapotPositions.byteLength;
118 g_tangentsOffset = g_normalsOffset + teapotNormals.byteLength;
119 g_binormalsOffset = g_tangentsOffset + teapotTangents.byteLength;
120 g_texCoordsOffset = g_binormalsOffset + teapotBinormals.byteLength;
121 gl.bufferSubData(gl.ARRAY_BUFFER, 0, teapotPositions);
122 gl.bufferSubData(gl.ARRAY_BUFFER, g_normalsOffset, teapotNormals);
123 gl.bufferSubData(gl.ARRAY_BUFFER, g_tangentsOffset, teapotTangents);
124 gl.bufferSubData(gl.ARRAY_BUFFER, g_binormalsOffset, teapotBinormals);
125 gl.bufferSubData(gl.ARRAY_BUFFER, g_texCoordsOffset, teapotTexCoords);
126
127 g_elementVbo = gl.createBuffer();
128 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, g_elementVbo);
129 gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, teapotIndices, gl.STATIC_DRAW);
130 g_numElements = teapotIndices.length;
131 }
132
133 var bumpReflectVertexSource = [
134 "attribute vec3 g_Position;",
135 "attribute vec3 g_TexCoord0;",
136 "attribute vec3 g_Tangent;",
137 "attribute vec3 g_Binormal;",
138 "attribute vec3 g_Normal;",
139 "",
140 "uniform mat4 world;",
141 "uniform mat4 worldInverseTranspose;",
142 "uniform mat4 worldViewProj;",
143 "uniform mat4 viewInverse;",
144 "",
145 "varying vec2 texCoord;",
146 "varying vec3 worldEyeVec;",
147 "varying vec3 worldNormal;",
148 "varying vec3 worldTangent;",
149 "varying vec3 worldBinorm;",
150 "",
151 "void main() {",
152 " gl_Position = worldViewProj * vec4(g_Position.xyz, 1.);",
153 " texCoord.xy = g_TexCoord0.xy;",
154 " worldNormal = (worldInverseTranspose * vec4(g_Normal, 1.)).xyz;",
155 " worldTangent = (worldInverseTranspose * vec4(g_Tangent, 1.)).xyz;",
156 " worldBinorm = (worldInverseTranspose * vec4(g_Binormal, 1.)).xyz;",
157 " vec3 worldPos = (world * vec4(g_Position, 1.)).xyz;",
158 " worldEyeVec = normalize(worldPos - viewInverse[3].xyz);",
159 "}"
160 ].join("\n");
161
162 var bumpReflectFragmentSource = [
163 "#ifdef GL_ES\n",
164 "precision highp float;\n",
165 "#endif\n",
166 "const float bumpHeight = 0.2;",
167 "",
168 "uniform sampler2D normalSampler;",
169 "uniform samplerCube envSampler;",
170 "",
171 "varying vec2 texCoord;",
172 "varying vec3 worldEyeVec;",
173 "varying vec3 worldNormal;",
174 "varying vec3 worldTangent;",
175 "varying vec3 worldBinorm;",
176 "",
177 "void main() {",
178 " vec2 bump = (texture2D(normalSampler, texCoord.xy).xy * 2.0 - 1.0) * bump Height;",
179 " vec3 normal = normalize(worldNormal);",
180 " vec3 tangent = normalize(worldTangent);",
181 " vec3 binormal = normalize(worldBinorm);",
182 " vec3 nb = normal + bump.x * tangent + bump.y * binormal;",
183 " nb = normalize(nb);",
184 " vec3 worldEye = normalize(worldEyeVec);",
185 " vec3 lookup = reflect(worldEye, nb);",
186 " vec4 color = textureCube(envSampler, lookup);",
187 " gl_FragColor = color;",
188 "}"
189 ].join("\n");
190
191 function loadShader(type, shaderSrc) {
192 var shader = gl.createShader(type);
193 if (shader == null) {
194 return null;
195 }
196 // Load the shader source
197 gl.shaderSource(shader, shaderSrc);
198 // Compile the shader
199 gl.compileShader(shader);
200 // Check the compile status
201 if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
202 var infoLog = gl.getShaderInfoLog(shader);
203 output("Error compiling shader:\n" + infoLog);
204 gl.deleteShader(shader);
205 return null;
206 }
207 return shader;
208 }
209
210 function initShaders() {
211 var vertexShader = loadShader(gl.VERTEX_SHADER, bumpReflectVertexSource);
212 var fragmentShader = loadShader(gl.FRAGMENT_SHADER, bumpReflectFragmentSourc e);
213 // Create the program object
214 var programObject = gl.createProgram();
215 if (programObject == null) {
216 output("Creating program failed");
217 return;
218 }
219 gl.attachShader(programObject, vertexShader);
220 gl.attachShader(programObject, fragmentShader);
221 // Bind attributes
222 gl.bindAttribLocation(programObject, 0, "g_Position");
223 gl.bindAttribLocation(programObject, 1, "g_TexCoord0");
224 gl.bindAttribLocation(programObject, 2, "g_Tangent");
225 gl.bindAttribLocation(programObject, 3, "g_Binormal");
226 gl.bindAttribLocation(programObject, 4, "g_Normal");
227 // Link the program
228 gl.linkProgram(programObject);
229 // Check the link status
230 var linked = gl.getProgramParameter(programObject, gl.LINK_STATUS);
231 if (!linked) {
232 var infoLog = gl.getProgramInfoLog(programObject);
233 output("Error linking program:\n" + infoLog);
234 gl.deleteProgram(programObject);
235 return;
236 }
237 g_programObject = programObject;
238 // Look up uniform locations
239 g_worldLoc = gl.getUniformLocation(g_programObject, "world");
240 g_worldInverseTransposeLoc = gl.getUniformLocation(g_programObject, "worldIn verseTranspose");
241 g_worldViewProjLoc = gl.getUniformLocation(g_programObject, "worldViewProj") ;
242 g_viewInverseLoc = gl.getUniformLocation(g_programObject, "viewInverse");
243 g_normalSamplerLoc = gl.getUniformLocation(g_programObject, "normalSampler") ;
244 g_envSamplerLoc = gl.getUniformLocation(g_programObject, "envSampler");
245 checkGLError();
246 }
247
248 function draw() {
249 // Note: the viewport is automatically set up to cover the entire Canvas.
250 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
251 checkGLError();
252
253 // For now, don't render if we have incomplete textures, just to
254 // avoid accidentally incurring OpenGL errors -- although we should
255 // be fully able to load textures in in the background
256 if (g_pendingTextureLoads > 0) {
257 gl.flush();
258 return;
259 }
260
261 // Set up the model, view and projection matrices
262 projection.loadIdentity();
263 projection.perspective(45, g_width / g_height, 10, 500);
264 view.loadIdentity();
265 view.translate(0, -10, -100.0);
266
267 // Add in camera controller's rotation
268 model.loadIdentity();
269 model.rotate(controller.xRot, 1, 0, 0);
270 model.rotate(controller.yRot, 0, 1, 0);
271
272 // Correct for initial placement and orientation of model
273 model.translate(0, -10, 0);
274 model.rotate(90, 1, 0, 0);
275
276 gl.useProgram(g_programObject);
277
278 // Compute necessary matrices
279 var mvp = new Matrix4x4();
280 mvp.multiply(model);
281 mvp.multiply(view);
282 mvp.multiply(projection);
283 var worldInverseTranspose = model.inverse();
284 worldInverseTranspose.transpose();
285 var viewInverse = view.inverse();
286
287 // Set up uniforms
288 gl.uniformMatrix4fv(g_worldLoc, gl.FALSE, new Float32Array(model.elements));
289 gl.uniformMatrix4fv(g_worldInverseTransposeLoc, gl.FALSE, new Float32Array(w orldInverseTranspose.elements));
290 gl.uniformMatrix4fv(g_worldViewProjLoc, gl.FALSE, new Float32Array(mvp.eleme nts));
291 gl.uniformMatrix4fv(g_viewInverseLoc, gl.FALSE, new Float32Array(viewInverse .elements));
292 gl.activeTexture(gl.TEXTURE0);
293 gl.bindTexture(gl.TEXTURE_2D, g_bumpTexture);
294 gl.uniform1i(g_normalSamplerLoc, 0);
295 gl.activeTexture(gl.TEXTURE1);
296 gl.bindTexture(gl.TEXTURE_CUBE_MAP, g_envTexture);
297 gl.uniform1i(g_envSamplerLoc, 1);
298 checkGLError();
299
300 // Bind and set up vertex streams
301 gl.bindBuffer(gl.ARRAY_BUFFER, g_vbo);
302 gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
303 gl.enableVertexAttribArray(0);
304 gl.vertexAttribPointer(1, 3, gl.FLOAT, false, 0, g_texCoordsOffset);
305 gl.enableVertexAttribArray(1);
306 gl.vertexAttribPointer(2, 3, gl.FLOAT, false, 0, g_tangentsOffset);
307 gl.enableVertexAttribArray(2);
308 gl.vertexAttribPointer(3, 3, gl.FLOAT, false, 0, g_binormalsOffset);
309 gl.enableVertexAttribArray(3);
310 gl.vertexAttribPointer(4, 3, gl.FLOAT, false, 0, g_normalsOffset);
311 gl.enableVertexAttribArray(4);
312 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, g_elementVbo);
313 checkGLError();
314 gl.drawElements(gl.TRIANGLES, g_numElements, gl.UNSIGNED_SHORT, 0);
315 gl.flush();
316 }
317
318 function loadTexture(src) {
319 var texture = gl.createTexture();
320 gl.bindTexture(gl.TEXTURE_2D, texture);
321 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
322 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
323 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
324 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
325 ++g_pendingTextureLoads;
326 var image = new Image();
327 image.onload = function() {
328 --g_pendingTextureLoads;
329 gl.bindTexture(gl.TEXTURE_2D, texture);
330 gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
331 gl.texImage2D(
332 gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
333 checkGLError();
334 draw();
335 waitForFinish();
336 };
337 image.src = src;
338 return texture;
339 }
340
341 function loadCubeMap(base, suffix) {
342 var texture = gl.createTexture();
343 gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);
344 checkGLError();
345 gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
346 checkGLError();
347 gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
348 checkGLError();
349 // FIXME: TEXTURE_WRAP_R doesn't exist in OpenGL ES?!
350 // gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_R, gl.CLAMP_TO_EDG E);
351 // checkGLError();
352 gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
353 checkGLError();
354 gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
355 checkGLError();
356 var faces = [["posx", gl.TEXTURE_CUBE_MAP_POSITIVE_X],
357 ["negx", gl.TEXTURE_CUBE_MAP_NEGATIVE_X],
358 ["posy", gl.TEXTURE_CUBE_MAP_POSITIVE_Y],
359 ["negy", gl.TEXTURE_CUBE_MAP_NEGATIVE_Y],
360 ["posz", gl.TEXTURE_CUBE_MAP_POSITIVE_Z],
361 ["negz", gl.TEXTURE_CUBE_MAP_NEGATIVE_Z]];
362 for (var i = 0; i < faces.length; i++) {
363 var url = base + "-" + faces[i][0] + "." + suffix;
364 var face = faces[i][1];
365 ++g_pendingTextureLoads;
366 var image = new Image();
367 // Javascript has function, not block, scope.
368 // See "JavaScript: The Good Parts", Chapter 4, "Functions",
369 // section "Scope".
370 image.onload = function(texture, face, image, url) {
371 return function() {
372 --g_pendingTextureLoads;
373 gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);
374 gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
375 gl.texImage2D(
376 face, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
377 checkGLError();
378 draw();
379 waitForFinish();
380 }
381 }(texture, face, image, url);
382 image.src = url;
383 }
384 return texture;
385 }
386
387 function waitForFinish() {
388 if (g_pendingTextureLoads == 0) {
389 domAutomationController.setAutomationId(1);
390 domAutomationController.send("ok");
391 }
392 }
OLDNEW
« no previous file with comments | « chrome/test/data/gpu/webgl_teapot/teapot_files/context.js ('k') | chrome/test/data/gpu/webgl_teapot/teapot_files/matrix4x4.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698