| 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 |