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

Side by Side Diff: samples/openglui/src/openglui_canvas_tests.dart

Issue 12390045: Added a rudimentary DOM, to assist with event dispatch. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 9 months 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
« no previous file with comments | « runtime/embedders/openglui/emulator/emulator_embedder.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 // Canvas API tests. Some of these are adapted from: 5 // Canvas API tests. Some of these are adapted from:
6 // 6 //
7 // http://www.html5canvastutorials.com/ 7 // http://www.html5canvastutorials.com/
8 8
9 library openglui_canvas_tests; 9 library openglui_canvas_tests;
10 10
11 import 'gl.dart'; 11 import 'gl.dart';
12 import 'dart:math' as Math; 12 import 'dart:math' as Math;
13 13
14 var ctx; 14 var ctx;
15 var width, height; 15 var width, height;
16 bool isDirty = true; 16 bool isDirty = true;
17 var canvas; 17 var canvas;
18 18
19 void resize(int w, int h) { 19 void resize(int w, int h) {
20 width = w; 20 width = w;
21 height = h; 21 height = h;
22 } 22 }
23 23
24 void setup(canvasp, int w, int h) { 24 void setup(canvasp, int w, int h) {
25 if (canvasp == null) { 25 if (canvasp == null) {
26 log("Allocating canvas"); 26 log("Allocating canvas");
27 canvas = new CanvasElement(width: w, height: h); 27 canvas = new CanvasElement(width: w, height: h);
28 document.body.nodes.add(canvas);
28 } else { 29 } else {
29 log("Using parent canvas"); 30 log("Using parent canvas");
30 canvas = canvasp; 31 canvas = canvasp;
31 // called from gl_driver.dart.
32 // This is a kludge; we need a clean way of handling events.
33 canvas.on.mouseDown.add((e) {
34 ++testnum;
35 });
36 } 32 }
33 canvas.onMouseDown.listen((e) {
34 ++testnum;
35 isDirty = true;
36 });
37 canvas.onKeyDown.listen((e) {
38 ++testnum;
39 isDirty = true;
40 });
37 ctx = canvas.getContext("2d"); 41 ctx = canvas.getContext("2d");
38 if (ctx == null) { 42 if (ctx == null) {
39 throw "Failed to get 2D context"; 43 throw "Failed to get 2D context";
40 } 44 }
41 resize(w, h); 45 resize(w, h);
42 log("Done setup"); 46 log("Done setup");
43 } 47 }
44 48
45 resetCanvas() { 49 resetCanvas() {
46 ctx.globalCompositeOperation = "source-over"; 50 ctx.globalCompositeOperation = "source-over";
(...skipping 595 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 646
643 ctx.beginPath(); 647 ctx.beginPath();
644 ctx.rect(myRectangle.x, myRectangle.y, myRectangle.width, myRectangle.height); 648 ctx.rect(myRectangle.x, myRectangle.y, myRectangle.width, myRectangle.height);
645 ctx.fillStyle = '#8ED6FF'; 649 ctx.fillStyle = '#8ED6FF';
646 ctx.fill(); 650 ctx.fill();
647 ctx.lineWidth = myRectangle.borderWidth; 651 ctx.lineWidth = myRectangle.borderWidth;
648 ctx.strokeStyle = 'black'; 652 ctx.strokeStyle = 'black';
649 ctx.stroke(); 653 ctx.stroke();
650 } 654 }
651 655
652 int testnum = -1; // Start with latest. 656 int testnum = 0; // Set this to -1 to start with last test.
653 657
654 void update() { 658 void update() {
655 if (testnum == 0) { 659 if (testnum == 0) {
656 anim(); 660 anim();
657 return; 661 return;
658 } 662 }
659 if (!isDirty) return; 663 if (!isDirty) return;
660 switch(testnum) { 664 switch(testnum) {
661 case 1: 665 case 1:
662 helloWorld(); 666 helloWorld();
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 break; 721 break;
718 case 20: 722 case 20:
719 shear(); 723 shear();
720 break; 724 break;
721 case 21: 725 case 21:
722 composite(); 726 composite();
723 break; 727 break;
724 case 22: 728 case 22:
725 smiley(); 729 smiley();
726 break; 730 break;
731 case 23:
732 var rayTracer = new RayTracer();
733 rayTracer.render(defaultScene(), ctx, width, height);
734 break;
727 default: 735 default:
728 if (testnum < 0) { 736 if (testnum < 0) {
729 testnum = 22; 737 testnum = 23;
730 } else { 738 } else {
731 testnum = 0; 739 testnum = 0;
732 } 740 }
733 update(); 741 update();
734 break; 742 break;
735 } 743 }
736 isDirty = false; 744 isDirty = false;
737 } 745 }
738 746
739 /* 747 // Raytracer adapted from https://gist.github.com/mythz/3817303.
740 TODO(gram): below are the current entry points for input events for the 748
741 native code version. We need to integrate these somehow with the WebGL 749 Scene defaultScene() =>
742 version: 750 new Scene(
743 */ 751 [new Plane(new Vector(0.0, 1.0, 0.0), 0.0, Surfaces.checkerboard),
744 onMotionDown(num when, num x, num y) { 752 new Sphere(new Vector(0.0, 1.0, -0.25), 1.0, Surfaces.shiny),
745 ++testnum; 753 new Sphere(new Vector(-1.0, 0.5, 1.5), 0.5, Surfaces.shiny)],
746 isDirty = true; 754 [new Light(new Vector(-2.0, 2.5, 0.0), new Color(0.49, 0.07, 0.07) ),
747 log("Marking dirty"); 755 new Light(new Vector(1.5, 2.5, 1.5), new Color(0.07, 0.07, 0.49) ),
748 } 756 new Light(new Vector(1.5, 2.5, -1.5), new Color(0.07, 0.49, 0.071) ),
749 onMotionUp(num when, num x, num y) {} 757 new Light(new Vector(0.0, 3.5, 0.0), new Color(0.21, 0.21, 0.35) )],
750 onMotionMove(num when, num x, num y) {} 758 new Camera(new Vector(3.0, 2.0, 4.0), new Vector(-1.0, 0.5, 0.0))
751 onMotionCancel(num when, num x, num y) {} 759 );
752 onMotionOutside(num when, num x, num y) {} 760
753 onMotionPointerDown(num when, num x, num y) { 761
754 ++testnum; 762 class Vector {
755 isDirty = true; 763 num x, y, z;
756 log("Marking dirty"); 764 Vector(this.x, this.y, this.z);
757 } 765
758 766 operator -(Vector v) => new Vector(x - v.x, y - v.y, z - v.z);
759 onMotionPointerUp(num when, num x, num y) {} 767 operator +(Vector v) => new Vector(x + v.x, y + v.y, z + v.z);
760 768 static times(num k, Vector v) => new Vector(k * v.x, k * v.y, k * v.z);
761 onKeyDown(num when, int flags, int keycode, int metastate, int repeat) { 769 static num dot(Vector v1, Vector v2) =>
762 if (keycode == 32) { 770 v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
763 ++testnum; 771 static num mag(Vector v) => Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
764 isDirty = true; 772 static Vector norm(Vector v) {
765 log("Marking dirty"); 773 var _mag = mag(v);
766 } 774 var div = _mag == 0 ? double.INFINITY : 1.0 / _mag;
767 } 775 return times(div, v);
768 776 }
769 onKeyUp(num when, int flags, int keycode, int metastate, int repeat) {} 777 static Vector cross(Vector v1, Vector v2) {
770 778 return new Vector(v1.y * v2.z - v1.z * v2.y,
771 onKeyMultiple(num when, int flags, int keycode, int metastate, int repeat) { 779 v1.z * v2.x - v1.x * v2.z,
772 } 780 v1.x * v2.y - v1.y * v2.x);
773 781 }
774 782 }
783
784 class Color {
785 num r, g, b;
786 static final white = new Color(1.0, 1.0, 1.0);
787 static final grey = new Color(0.5, 0.5, 0.5);
788 static final black = new Color(0.0, 0.0, 0.0);
789 static final background = Color.black;
790 static final defaultColor = Color.black;
791
792 Color(this.r,this.g,this.b);
793 static scale(num k, Color v) => new Color(k * v.r, k * v.g, k * v.b);
794 operator +(Color v) => new Color(r + v.r, g + v.g, b + v.b);
795 operator *(Color v) => new Color(r * v.r, g * v.g, b * v.b);
796 static _intColor(num d) => ((d > 1 ? 1 : d) * 255).toInt();
797 static String toDrawingRGB(Color c) =>
798 "rgb(${_intColor(c.r)}, ${_intColor(c.g)}, ${_intColor(c.b)})";
799 }
800
801 class Camera {
802 Vector pos, forward, right, up;
803 Camera (this.pos, Vector lookAt) {
804 var down = new Vector(0.0, -1.0, 0.0);
805 forward = Vector.norm(lookAt - pos);
806 right = Vector.times(1.5, Vector.norm(Vector.cross(forward, down)));
807 up = Vector.times(1.5, Vector.norm(Vector.cross(forward, right)));
808 }
809 }
810
811 class Ray {
812 Vector start, dir;
813 Ray([this.start, this.dir]);
814 }
815
816 class Intersection {
817 Thing thing;
818 Ray ray;
819 num dist;
820 Intersection(this.thing, this.ray, this.dist);
821 }
822
823 class Light {
824 Vector pos;
825 Color color;
826 Light(this.pos, this.color);
827 }
828
829 abstract class Surface {
830 int roughness;
831 Color diffuse(Vector pos);
832 Color specular(Vector pos);
833 num reflect(Vector pos);
834 }
835
836 abstract class Thing {
837 Intersection intersect(Ray ray);
838 Vector normal(Vector pos);
839 Surface surface;
840 }
841
842 class Scene {
843 List<Thing> things;
844 List<Light> lights;
845 Camera camera;
846 Scene([this.things,this.lights,this.camera]);
847 }
848
849 class Sphere implements Thing {
850 num radius2, radius;
851 Vector center;
852 Surface surface;
853
854 Sphere (this.center, this.radius, this.surface) {
855 this.radius2 = radius * radius;
856 }
857 normal(Vector pos) => Vector.norm(pos - center);
858 intersect(Ray ray) {
859 var eo = this.center - ray.start;
860 var v = Vector.dot(eo, ray.dir);
861 var dist = 0;
862 if (v >= 0) {
863 var disc = this.radius2 - (Vector.dot(eo, eo) - v * v);
864 if (disc >= 0) {
865 dist = v - Math.sqrt(disc);
866 }
867 }
868 return dist == 0 ? null : new Intersection(this, ray, dist);
869 }
870 }
871
872 class Plane implements Thing {
873 Vector norm;
874 num offset;
875 Surface surface;
876 Plane(this.norm, this.offset, this.surface);
877 Vector normal(Vector pos) => norm;
878 Intersection intersect(Ray ray) {
879 var denom = Vector.dot(norm, ray.dir);
880 if (denom > 0) {
881 return null;
882 } else {
883 var dist = (Vector.dot(norm, ray.start) + offset) / (-denom);
884 return new Intersection(this, ray, dist);
885 }
886 }
887 }
888
889 class CustomSurface implements Surface {
890 Color diffuseColor, specularColor;
891 int roughness;
892 num reflectPos;
893 CustomSurface(this.diffuseColor, this.specularColor,
894 this.reflectPos, this.roughness);
895 diffuse(pos) => diffuseColor;
896 specular(pos) => specularColor;
897 reflect(pos) => reflectPos;
898 }
899
900 class CheckerBoardSurface implements Surface {
901 int roughness;
902 CheckerBoardSurface([this.roughness=150]);
903 diffuse(pos) => (pos.z.floor() + pos.x.floor()) % 2 != 0
904 ? Color.white
905 : Color.black;
906 specular(pos) => Color.white;
907 reflect(pos) => (pos.z.floor() + pos.x.floor()) % 2 != 0 ? 0.1 : 0.7;
908 }
909
910 class Surfaces {
911 static final shiny = new CustomSurface(Color.white, Color.grey, 0.7, 250);
912 static final checkerboard = new CheckerBoardSurface();
913 }
914
915 class RayTracer {
916 num _maxDepth = 5;
917
918 Intersection _intersections(Ray ray, Scene scene) {
919 var closest = double.INFINITY;
920 Intersection closestInter = null;
921 for (Thing thing in scene.things) {
922 var inter = thing.intersect(ray);
923 if (inter != null && inter.dist < closest) {
924 closestInter = inter;
925 closest = inter.dist;
926 }
927 }
928 return closestInter;
929 }
930
931 _testRay(Ray ray, Scene scene) {
932 var isect = _intersections(ray, scene);
933 return isect != null ? isect.dist : null;
934 }
935
936 _traceRay(Ray ray, Scene scene, num depth) {
937 var isect = _intersections(ray, scene);
938 return isect == null ? Color.background : _shade(isect, scene, depth);
939 }
940
941 _shade(Intersection isect, Scene scene, num depth) {
942 var d = isect.ray.dir;
943 var pos = Vector.times(isect.dist, d) + isect.ray.start;
944 var normal = isect.thing.normal(pos);
945 var reflectDir = d -
946 Vector.times(2, Vector.times(Vector.dot(normal, d), normal));
947 var naturalColor = Color.background +
948 _getNaturalColor(isect.thing, pos, normal, reflectDir, scene);
949 var reflectedColor = (depth >= _maxDepth) ? Color.grey :
950 _getReflectionColor(isect.thing, pos, normal, reflectDir,
951 scene, depth);
952 return naturalColor + reflectedColor;
953 }
954
955 _getReflectionColor(Thing thing, Vector pos, Vector normal, Vector rd,
956 Scene scene, num depth) =>
957 Color.scale(thing.surface.reflect(pos),
958 _traceRay(new Ray(pos, rd), scene, depth + 1));
959
960 _getNaturalColor(Thing thing, Vector pos, Vector norm, Vector rd,
961 Scene scene) {
962 var addLight = (col, light) {
963 var ldis = light.pos - pos;
964 var livec = Vector.norm(ldis);
965 var neatIsect = _testRay(new Ray(pos, livec), scene);
966 var isInShadow = neatIsect == null ? false :
967 (neatIsect <= Vector.mag(ldis));
968 if (isInShadow) {
969 return col;
970 } else {
971 var illum = Vector.dot(livec, norm);
972 var lcolor = (illum > 0) ? Color.scale(illum, light.color)
973 : Color.defaultColor;
974 var specular = Vector.dot(livec, Vector.norm(rd));
975 var scolor = (specular > 0)
976 ? Color.scale(Math.pow(specular, thing.surface.roughness),
977 light.color)
978 : Color.defaultColor;
979 return col + (thing.surface.diffuse(pos) * lcolor)
980 + (thing.surface.specular(pos) * scolor);
981 }
982 };
983 return scene.lights.reduce(Color.defaultColor, addLight);
984 }
985
986 render(Scene scene, CanvasRenderingContext2D ctx, num screenWidth,
987 num screenHeight) {
988 var getPoint = (x, y, camera) {
989 var recenterX = (x) => (x - (screenWidth / 2.0)) / 2.0 / screenWidth;
990 var recenterY = (y) => - (y - (screenHeight / 2.0)) / 2.0 / screenHeight;
991 return Vector.norm(camera.forward
992 + Vector.times(recenterX(x), camera.right)
993 + Vector.times(recenterY(y), camera.up));
994 };
995 for (int y = 0; y < screenHeight; y++) {
996 for (int x = 0; x < screenWidth; x++) {
997 var color = _traceRay(new Ray(scene.camera.pos,
998 getPoint(x, y, scene.camera) ), scene, 0);
999 ctx.fillStyle = Color.toDrawingRGB(color);
1000 ctx.fillRect(x, y, x + 1, y + 1);
1001 }
1002 }
1003 }
1004 }
1005
1006
1007
1008
OLDNEW
« no previous file with comments | « runtime/embedders/openglui/emulator/emulator_embedder.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698