OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 // | 4 // |
5 // This sample is based upon the Ray Tracer sample by Jonas Sicking at: | 5 // This sample is based upon the Ray Tracer sample by Jonas Sicking at: |
6 // http://www.khronos.org/webgl/wiki/Demo_Repository | 6 // http://www.khronos.org/webgl/wiki/Demo_Repository |
7 | 7 |
8 /** | 8 /** |
9 * A sample GL application. | 9 * A sample GL application. |
10 */ | 10 */ |
11 library raytrace; | 11 library raytrace; |
12 | 12 |
13 import 'gl.dart'; | 13 import 'gl.dart'; |
14 import 'dart:math' as Math; | 14 import 'dart:math' as Math; |
15 | 15 |
| 16 // Note: The first line of the fragment shader ("precision mediump float") |
| 17 // is not portable. It is required for WebGL and OpenGL ES. Desktop OpenGL |
| 18 // does not use precision specifiers. Some desktop systems treat this as a |
| 19 // no-op and some treat it as a syntax error. In particular, this line needs |
| 20 // to be removed to this this shader on a MAc. |
16 const FRAGMENT_PROGRAM = """ | 21 const FRAGMENT_PROGRAM = """ |
17 precision mediump float; | 22 precision mediump float; |
18 | 23 |
19 const vec3 lightDir = vec3(0.577350269, 0.577350269, -0.577350269); | 24 const vec3 lightDir = vec3(0.577350269, 0.577350269, -0.577350269); |
20 varying vec3 vPosition; | 25 varying vec3 vPosition; |
21 uniform vec3 cameraPos; | 26 uniform vec3 cameraPos; |
22 uniform vec3 sphere1Center; | 27 uniform vec3 sphere1Center; |
23 uniform vec3 sphere2Center; | 28 uniform vec3 sphere2Center; |
24 uniform vec3 sphere3Center; | 29 uniform vec3 sphere3Center; |
25 | 30 |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 vPosition = aPlotPosition; | 153 vPosition = aPlotPosition; |
149 } | 154 } |
150 """; | 155 """; |
151 | 156 |
152 loadShader(final type, final program) { | 157 loadShader(final type, final program) { |
153 final shader = gl.createShader(type); | 158 final shader = gl.createShader(type); |
154 gl.shaderSource(shader, program); | 159 gl.shaderSource(shader, program); |
155 gl.compileShader(shader); | 160 gl.compileShader(shader); |
156 if (gl.getShaderParameter(shader, WebGLRenderingContext.COMPILE_STATUS) != tru
e) { | 161 if (gl.getShaderParameter(shader, WebGLRenderingContext.COMPILE_STATUS) != tru
e) { |
157 final error = gl.getShaderInfoLog(shader); | 162 final error = gl.getShaderInfoLog(shader); |
| 163 log(error); |
158 throw new Exception("Shader compilation error: $error"); | 164 throw new Exception("Shader compilation error: $error"); |
159 } | 165 } |
160 | 166 |
161 return shader; | 167 return shader; |
162 } | 168 } |
163 | 169 |
164 var shaderProgram; | 170 var shaderProgram; |
165 var aVertexPosition; | 171 var aVertexPosition; |
166 var aPlotPosition; | 172 var aPlotPosition; |
167 var cameraPos; | 173 var cameraPos; |
168 var sphere1Center; | 174 var sphere1Center; |
169 var sphere2Center; | 175 var sphere2Center; |
170 var sphere3Center; | 176 var sphere3Center; |
171 var ratio; | 177 var ratio; |
172 | 178 |
173 void initShaders() { | 179 void initShaders() { |
174 var vertexShader = loadShader(WebGLRenderingContext.VERTEX_SHADER, VERTEX_PROG
RAM); | 180 var vertexShader = loadShader(WebGLRenderingContext.VERTEX_SHADER, |
175 var fragmentShader = loadShader(WebGLRenderingContext.FRAGMENT_SHADER, FRAGMEN
T_PROGRAM); | 181 VERTEX_PROGRAM); |
| 182 var fragmentShader = loadShader(WebGLRenderingContext.FRAGMENT_SHADER, |
| 183 FRAGMENT_PROGRAM); |
176 | 184 |
177 shaderProgram = gl.createProgram(); | 185 shaderProgram = gl.createProgram(); |
178 if (shaderProgram == 0) { | 186 if (shaderProgram == 0) { |
179 throw new Exception("Could not create program."); | 187 throw new Exception("Could not create program."); |
180 } | 188 } |
181 | 189 |
182 gl.attachShader(shaderProgram, vertexShader); | 190 gl.attachShader(shaderProgram, vertexShader); |
183 gl.attachShader(shaderProgram, fragmentShader); | 191 gl.attachShader(shaderProgram, fragmentShader); |
184 gl.linkProgram(shaderProgram); | 192 gl.linkProgram(shaderProgram); |
185 | 193 |
186 if (gl.getProgramParameter(shaderProgram, WebGLRenderingContext.LINK_STATUS) !
= true) { | 194 if (gl.getProgramParameter(shaderProgram, WebGLRenderingContext.LINK_STATUS) !
= true) { |
187 final error = gl.getProgramInfoLog(shaderProgram); | 195 final error = gl.getProgramInfoLog(shaderProgram); |
188 throw new Exception("Program compilation error: $error"); | 196 throw new Exception("Program compilation error: $error"); |
189 } | 197 } |
190 | 198 |
191 gl.useProgram(shaderProgram); | 199 gl.useProgram(shaderProgram); |
192 | 200 |
193 aVertexPosition = gl.getAttribLocation(shaderProgram, "aVertexPosition"); | 201 aVertexPosition = gl.getAttribLocation(shaderProgram, "aVertexPosition"); |
194 gl.enableVertexAttribArray(aVertexPosition); | 202 gl.enableVertexAttribArray(aVertexPosition); |
195 | 203 |
196 aPlotPosition = gl.getAttribLocation(shaderProgram, "aPlotPosition"); | 204 aPlotPosition = gl.getAttribLocation(shaderProgram, "aPlotPosition"); |
197 gl.enableVertexAttribArray(aPlotPosition); | 205 gl.enableVertexAttribArray(aPlotPosition); |
198 | 206 |
199 cameraPos = gl.getUniformLocation(shaderProgram, "cameraPos"); | 207 cameraPos = gl.getUniformLocation(shaderProgram, "cameraPos"); |
200 sphere1Center = gl.getUniformLocation(shaderProgram, "sphere1Center"); | 208 sphere1Center = gl.getUniformLocation(shaderProgram, "sphere1Center"); |
201 sphere2Center = gl.getUniformLocation(shaderProgram, "sphere2Center"); | 209 sphere2Center = gl.getUniformLocation(shaderProgram, "sphere2Center"); |
202 sphere3Center = gl.getUniformLocation(shaderProgram, "sphere3Center"); | 210 sphere3Center = gl.getUniformLocation(shaderProgram, "sphere3Center"); |
203 } | 211 } |
204 | 212 |
| 213 // TODO(gram): This should go away at some point. For now it is a kludge |
| 214 // to allow us to run same .dart file with WebGL and natively; the WebGL |
| 215 // version will set this to true. |
| 216 var wrapVertexArray = false; |
| 217 |
| 218 wrapVertices(a) => wrapVertexArray ? (new Float32Array.fromList(a)) : a; |
| 219 |
205 void initBuffers() { | 220 void initBuffers() { |
206 var vertexPositionBuffer = gl.createBuffer(); | 221 var vertexPositionBuffer = gl.createBuffer(); |
207 gl.bindBuffer(WebGLRenderingContext.ARRAY_BUFFER, vertexPositionBuffer); | 222 gl.bindBuffer(WebGLRenderingContext.ARRAY_BUFFER, vertexPositionBuffer); |
208 var vertices = [ | 223 var vertices = [ |
209 1.0, 1.0, | 224 1.0, 1.0, |
210 -1.0, 1.0, | 225 -1.0, 1.0, |
211 1.0, -1.0, | 226 1.0, -1.0, |
212 -1.0, -1.0, | 227 -1.0, -1.0, |
213 ]; | 228 ]; |
214 | 229 |
215 gl.bufferData(WebGLRenderingContext.ARRAY_BUFFER, new Float32Array.fromList(ve
rtices), WebGLRenderingContext.STATIC_DRAW); | 230 gl.bufferData(WebGLRenderingContext.ARRAY_BUFFER, wrapVertices(vertices), |
216 gl.vertexAttribPointer(aVertexPosition, 2, WebGLRenderingContext.FLOAT, false,
0, 0); | 231 WebGLRenderingContext.STATIC_DRAW); |
| 232 gl.bindBuffer(WebGLRenderingContext.ARRAY_BUFFER, vertexPositionBuffer); |
| 233 gl.vertexAttribPointer(aVertexPosition, 2, WebGLRenderingContext.FLOAT, |
| 234 false,0, 0); |
217 | 235 |
218 var plotPositionBuffer = gl.createBuffer(); | 236 var plotPositionBuffer = gl.createBuffer(); |
219 gl.bindBuffer(WebGLRenderingContext.ARRAY_BUFFER, plotPositionBuffer); | 237 gl.bindBuffer(WebGLRenderingContext.ARRAY_BUFFER, plotPositionBuffer); |
220 gl.vertexAttribPointer(aPlotPosition, 3, WebGLRenderingContext.FLOAT, false, 0
, 0); | 238 gl.vertexAttribPointer(aPlotPosition, 3, WebGLRenderingContext.FLOAT, |
| 239 false, 0, 0); |
221 } | 240 } |
222 | 241 |
223 class Vector { | 242 class Vector { |
224 var x; | 243 var x; |
225 var y; | 244 var y; |
226 var z; | 245 var z; |
227 | |
228 Vector(this.x, this.y, this.z); | 246 Vector(this.x, this.y, this.z); |
229 } | 247 } |
230 | 248 |
| 249 // TODO(gram): This should be using vector_math. |
231 crossProd(v1, v2) => | 250 crossProd(v1, v2) => |
232 new Vector(v1.y*v2.z - v2.y*v1.z, | 251 new Vector(v1.y*v2.z - v2.y*v1.z, |
233 v1.z*v2.x - v2.z*v1.x, | 252 v1.z*v2.x - v2.z*v1.x, |
234 v1.x*v2.y - v2.x*v1.y); | 253 v1.x*v2.y - v2.x*v1.y); |
235 | 254 |
236 Vector normalize(v) { | 255 Vector normalize(v) { |
237 var l = 1 / Math.sqrt(v.x*v.x + v.y*v.y + v.z*v.z); | 256 var l = 1 / Math.sqrt(v.x*v.x + v.y*v.y + v.z*v.z); |
238 return new Vector( v.x*l, v.y*l, v.z*l ); | 257 return new Vector( v.x*l, v.y*l, v.z*l ); |
239 } | 258 } |
240 | 259 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 // cameraCenter + cameraUp + cameraLeft * ratio | 297 // cameraCenter + cameraUp + cameraLeft * ratio |
279 var cameraTopLeft = vectAdd(vectAdd(cameraCenter, cameraUp), | 298 var cameraTopLeft = vectAdd(vectAdd(cameraCenter, cameraUp), |
280 vectMul(cameraLeft, ratio)); | 299 vectMul(cameraLeft, ratio)); |
281 var cameraBotLeft = vectAdd(vectSub(cameraCenter, cameraUp), | 300 var cameraBotLeft = vectAdd(vectSub(cameraCenter, cameraUp), |
282 vectMul(cameraLeft, ratio)); | 301 vectMul(cameraLeft, ratio)); |
283 var cameraTopRight = vectSub(vectAdd(cameraCenter, cameraUp), | 302 var cameraTopRight = vectSub(vectAdd(cameraCenter, cameraUp), |
284 vectMul(cameraLeft, ratio)); | 303 vectMul(cameraLeft, ratio)); |
285 var cameraBotRight = vectSub(vectSub(cameraCenter, cameraUp), | 304 var cameraBotRight = vectSub(vectSub(cameraCenter, cameraUp), |
286 vectMul(cameraLeft, ratio)); | 305 vectMul(cameraLeft, ratio)); |
287 | 306 |
288 // corners = [1.2, 1, -12, -1.2, 1, -12, 1.2, -1, -12, -1.2, -1, -12]; | |
289 var corners = []; | 307 var corners = []; |
290 pushVec(cameraTopRight, corners); | 308 pushVec(cameraTopRight, corners); |
291 pushVec(cameraTopLeft, corners); | 309 pushVec(cameraTopLeft, corners); |
292 pushVec(cameraBotRight, corners); | 310 pushVec(cameraBotRight, corners); |
293 pushVec(cameraBotLeft, corners); | 311 pushVec(cameraBotLeft, corners); |
294 var cornersArray = new Float32Array.fromList(corners); | 312 |
295 gl.bufferData(WebGLRenderingContext.ARRAY_BUFFER, cornersArray, | 313 gl.bufferData(WebGLRenderingContext.ARRAY_BUFFER, wrapVertices(corners), |
296 WebGLRenderingContext.STATIC_DRAW); | 314 WebGLRenderingContext.STATIC_DRAW); |
297 | 315 |
298 gl.uniform3f(cameraPos, cameraFrom.x, cameraFrom.y, cameraFrom.z); | 316 gl.uniform3f(cameraPos, cameraFrom.x, cameraFrom.y, cameraFrom.z); |
299 gl.uniform3f(sphere1Center, x1, y1, z1); | 317 gl.uniform3f(sphere1Center, x1, y1, z1); |
300 gl.uniform3f(sphere2Center, x2, y2, z2); | 318 gl.uniform3f(sphere2Center, x2, y2, z2); |
301 gl.uniform3f(sphere3Center, x3, y3, z3); | 319 gl.uniform3f(sphere3Center, x3, y3, z3); |
302 | 320 |
303 gl.drawArrays(WebGLRenderingContext.TRIANGLE_STRIP, 0, 4); | 321 gl.drawArrays(WebGLRenderingContext.TRIANGLE_STRIP, 0, 4); |
304 | 322 |
305 t += 0.03; | 323 t += 0.03; |
306 if (t > Math.PI * 200) { | 324 if (t > Math.PI * 200) { |
307 t -= Math.PI * 200; | 325 t -= Math.PI * 200; |
308 } | 326 } |
309 } | 327 } |
310 | 328 |
311 void setup() { | 329 void setup(int width, int height) { |
312 initShaders(); | 330 initShaders(); |
313 gl.clearColor(0.0, 0.0, 0.0, 1.0); | 331 gl.clearColor(0.0, 0.0, 0.0, 1.0); |
314 gl.clearDepth(1.0); | 332 gl.clearDepth(1.0); |
315 initBuffers(); | 333 initBuffers(); |
| 334 resize(width, height); |
316 } | 335 } |
317 | 336 |
318 void resize(int width, int height) { | 337 void resize(int width, int height) { |
319 ratio = width / height; | 338 ratio = width / height; |
320 gl.viewport(0, 0, width, height); | 339 gl.viewport(0, 0, width, height); |
321 t -= 0.03; | 340 t -= 0.03; |
322 drawScene(); | 341 drawScene(); |
323 } | 342 } |
324 | 343 |
325 void draw() { | 344 void update() { |
326 drawScene(); | 345 drawScene(); |
327 } | 346 } |
| 347 |
| 348 /* |
| 349 TODO(gram): below are the current entry points for input events for the |
| 350 native code version. We need to integrate these somehow with the WebGL |
| 351 version: |
| 352 |
| 353 onMotionDown(num when, num x, num y) {} |
| 354 onMotionUp(num when, num x, num y) {} |
| 355 onMotionMove(num when, num x, num y) {} |
| 356 onMotionCancel(num when, num x, num y) {} |
| 357 onMotionOutside(num when, num x, num y) {} |
| 358 onMotionPointerDown(num when, num x, num y) {} |
| 359 onMotionPointerUp(num when, num x, num y) {} |
| 360 onKeyDown(num when, int flags, int keycode, int metastate, int repeat) {} |
| 361 onKeyUp(num when, int flags, int keycode, int metastate, int repeat) {} |
| 362 onKeyMultiple(num when, int flags, int keycode, int metastate, int repeat) { |
| 363 } |
| 364 */ |
| 365 |
OLD | NEW |