/* Source: http://www.ibiblio.org/e-notes/webgl/models/ethanol.html * http://www.worldofmolecules.com/3D/dopamine_3d.htm */ /// <summary> /// This is a javascript application. /// </summary> /// <param name="page">HTML document rendered by the web server which can now be enhanced.</param> public Application(IDefault page = null) { var prMatrix = new CanvasMatrix4(); var gl_viewportWidth = 500; var gl_viewportHeight = 500; var gl = new WebGLRenderingContext(); var canvas = gl.canvas.AttachToDocument(); #region AtResize Action AtResize = delegate { gl_viewportWidth = Native.window.Width; gl_viewportHeight = Native.window.Height; prMatrix = new CanvasMatrix4(); prMatrix.perspective(45f, (f)Native.window.aspect, 1f, 100f); canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportHeight); canvas.width = gl_viewportWidth; canvas.height = gl_viewportHeight; }; Native.window.onresize += e => { AtResize(); }; AtResize(); #endregion Native.document.body.style.overflow = IStyle.OverflowEnum.hidden; var h = 1f; var r1 = .5f; var r2 = .2f; #region requestPointerLock var __pointer_x = 0; var __pointer_y = 0; canvas.onmousedown += delegate { canvas.requestPointerLock(); }; canvas.onmousemove += e => { if (Native.Document.pointerLockElement == canvas) { __pointer_x += e.movementX; __pointer_y += e.movementY; } }; canvas.onmouseup += delegate { //Native.Document.exitPointerLock(); }; #endregion var prog = gl.createProgram( new GeometryVertexShader(), new GeometryFragmentShader() ); gl.linkProgram(prog); gl.useProgram(prog); var uniforms = prog.Uniforms(gl); var nPhi = 100; var nTheta = 50; var dPhi = 2 * Math.PI / nPhi; var dTheta = Math.PI / nTheta; var vertices = new IArray <float>(); var ind = new IArray <ushort>(); for (var j = 0; j <= nTheta; j++) { var Theta = j * dTheta; var cosTheta = Math.Cos(Theta); var sinTheta = Math.Sin(Theta); for (var i = 0; i <= nPhi; i++) { var Phi = i * dPhi; var cosPhi = Math.Cos(Phi); var sinPhi = Math.Sin(Phi); vertices.push((f)(cosPhi * sinTheta)); vertices.push((f)(-sinPhi * sinTheta)); vertices.push((f)(cosTheta)); } } for (var j = 0; j < nTheta; j++) { for (var i = 0; i <= nPhi; i++) { ind.push((ushort)(j * (nPhi + 1) + i)); ind.push((ushort)((j + 1) * (nPhi + 1) + i)); } } var posLocation = gl.getAttribLocation(prog, "aPos"); gl.enableVertexAttribArray((uint)posLocation); var posBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, posBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); gl.vertexAttribPointer((uint)posLocation, 3, gl.FLOAT, false, 0, 0); var indexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(ind.ToArray()), gl.STATIC_DRAW); //prMatrix.perspective(45, 1, .1, 100); gl.uniformMatrix4fv(gl.getUniformLocation(prog, "prMatrix"), false, new Float32Array(prMatrix.getAsArray())); var mvMatrix = new CanvasMatrix4(); var mvMatLoc = gl.getUniformLocation(prog, "mvMatrix"); gl.enable(gl.DEPTH_TEST); gl.depthFunc(gl.LEQUAL); gl.clearDepth(1.0f); gl.clearColor(0, 0, .8f, 1f); var xOffs = 0; var yOffs = 0; var drag = 0; var xRot = 0f; var yRot = 1f; var transl = -15.5f; #region drawScene Action drawScene = delegate { var rotMat = new CanvasMatrix4(); rotMat.makeIdentity(); #region draw Action <f, f, f, f, f, f, f> drawBall = (x, y, z, r, g, b, _scale) => { var scale = _scale * 1.4f; mvMatrix.makeIdentity(); mvMatrix.translate(x, y, z); mvMatrix.multRight(rotMat); mvMatrix.translate(0, 0, transl); gl.uniformMatrix4fv(mvMatLoc, false, new Float32Array(mvMatrix.getAsArray())); //var colorLoc = gl.getUniformLocation(prog, "color"); //var scaleLoc = gl.getUniformLocation(prog, "scale"); uniforms.color = new __vec3(r, g, b); uniforms.scale = scale; //gl.uniform1f(scaleLoc, scale); //gl.uniform3f(colorLoc, r, g, b); for (var i = 0; i < nTheta; i++) { gl.drawElements(gl.TRIANGLE_STRIP, 2 * (nPhi + 1), gl.UNSIGNED_SHORT, 4 * (nPhi + 1) * i); } }; Action <f, f, f, f> drawBall_white = (x, y, z, _scale) => drawBall(x, y, z, 1, 1, 1, _scale); Action <f, f, f, f> drawBall_red = (x, y, z, _scale) => drawBall(x, y, z, 1, 0, 0, _scale); Action <f, f, f, f> drawBall_blue = (x, y, z, _scale) => drawBall(x, y, z, 0, 0, 1, _scale); Action <f, f, f, f> drawBall_gray = (x, y, z, _scale) => drawBall(x, y, z, .3f, .3f, .3f, _scale); #endregion gl.viewport(0, 0, gl_viewportWidth, gl_viewportHeight); #region prMatrix gl.uniformMatrix4fv(gl.getUniformLocation(prog, "prMatrix"), false, new Float32Array(prMatrix.getAsArray())); #endregion gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); rotMat.rotate(xRot / 3, 1, 0, 0); rotMat.rotate(yRot / 3, 0, 1, 0); //yRot = 0; //xRot = 0; rotMat.rotate(__pointer_y * 1.0f, 1, 0, 0); rotMat.rotate(__pointer_x * 1.0f, 0, 1, 0); //__pointer_x = 0; //__pointer_y = 0; //http://en.wikipedia.org/wiki/Cyanogen #region C2N2 drawBall_blue(0, -3, 0, 1f); drawBall_gray(0, -1, 0, 1.2f); drawBall_gray(0, 1, 0, 1.2f); drawBall_blue(0, 3, 0, 1f); #endregion //#region C6H3 //drawBall_gray(2, -1, 0, 1.5f); //drawBall_gray(0, -2, 0, 1.5f); //drawBall_white(0, -3.5f, 0, 1f); //drawBall_gray(-2, -1, 0, 1.5f); //drawBall_gray(2, 1, 0, 1.5f); //drawBall_white(3 + 0.5f, 1.5f + 0.5f, 0, 1f); //drawBall_gray(0, 2, 0, 1.5f); //drawBall_white(0, 3.5f, 0, 1f); //drawBall_gray(-2, 1, 0, 1.5f); //#endregion //#region CH2-CH2 //drawBall_white(6, -1 + 1, -1.5f, 1f); //drawBall_gray(6, -1, 0, 1.5f); //drawBall_white(6, -1 + 1, 1.5f, 1f); //drawBall_white(4, -2 - 1, -1.5f, 1f); //drawBall_gray(4, -2, 0, 1.5f); //drawBall_white(4, -2 - 1, 1.5f, 1f); //#endregion //#region NH2 //drawBall_white(8, -2 - 1, -1.5f, 1f); //drawBall_blue(8, -2, 0, 1.5f); //drawBall_white(8, -2 - 1, 1.5f, 1f); //#endregion gl.flush(); }; #endregion #region mouse canvas.onmousedown += ev => { ev.preventDefault(); drag = 1; xOffs = ev.CursorX; yOffs = ev.CursorY; }; canvas.onmouseup += ev => { ev.preventDefault(); drag = 0; xOffs = ev.CursorX; yOffs = ev.CursorY; }; canvas.onmousemove += ev => { if (drag == 0) { return; } ev.preventDefault(); if (ev.shiftKey) { transl *= 1 + (ev.CursorY - yOffs) / 1000; yRot = -xOffs + ev.CursorX; } else { yRot = -xOffs + ev.CursorX; xRot = -yOffs + ev.CursorY; } xOffs = ev.CursorX; yOffs = ev.CursorY; drawScene(); }; #endregion #region onmousewheel canvas.onmousewheel += ev => { var del = 1.1f; if (ev.shiftKey) { del = 1.01f; } if (ev.WheelDirection > 0) { transl *= del; } else { transl *= (1 / del); } drawScene(); ev.PreventDefault(); }; #endregion #region IsDisposed var IsDisposed = false; this.Dispose = delegate { if (IsDisposed) { return; } IsDisposed = true; canvas.Orphanize(); }; #endregion #region requestFullscreen Native.Document.body.ondblclick += delegate { if (IsDisposed) { return; } // http://tutorialzine.com/2012/02/enhance-your-website-fullscreen-api/ Native.Document.body.requestFullscreen(); }; #endregion var c = 0; Native.window.onframe += delegate { if (IsDisposed) { return; } c++; xRot += 0.2f; yRot += 0.3f; drawScene(); }; //new IHTMLAnchor { "drag me to my.jsc-solutions.net" }.AttachToDocument().With( // dragme => // { // dragme.style.position = IStyle.PositionEnum.@fixed; // dragme.style.left = "1em"; // dragme.style.bottom = "1em"; // dragme.AllowToDragAsApplicationPackage(); // } //); }
/// <summary> /// This is a javascript application. /// </summary> /// <param name="page">HTML document rendered by the web server which can now be enhanced.</param> public Application(IDefault page = null) { var gl_viewportWidth = 500; var gl_viewportHeight = 500; var gl = new WebGLRenderingContext(); #region canvas var canvas = gl.canvas.AttachToDocument(); Native.document.body.style.overflow = IStyle.OverflowEnum.hidden; canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportHeight); canvas.width = gl_viewportWidth; canvas.height = gl_viewportHeight; #endregion var h = 1f; var r1 = .5f; var r2 = .2f; var nPhi = 500; var prog = gl.createProgram(); #region createShader Func<ScriptCoreLib.GLSL.Shader, WebGLShader> createShader = (src) => { var shader = gl.createShader(src); // verify if (gl.getShaderParameter(shader, gl.COMPILE_STATUS) == null) { Native.window.alert("error in SHADER:\n" + gl.getShaderInfoLog(shader)); throw new InvalidOperationException("shader failed"); } return shader; }; #endregion var vs = createShader(new GeometryVertexShader()); var fs = createShader(new GeometryFragmentShader()); gl.attachShader(prog, vs); gl.attachShader(prog, fs); gl.linkProgram(prog); gl.useProgram(prog); var pt = new IArray<float>(); var nt = new IArray<float>(); var Phi = 0.0; var dPhi = 2 * Math.PI / (nPhi - 1); var Nx = r1 - r2; var Ny = h; var N = (float)Math.Sqrt(Nx * Nx + Ny * Ny); Nx /= N; Ny /= N; for (var i = 0; i < nPhi; i++) { var cosPhi = Math.Cos(Phi); var sinPhi = Math.Sin(Phi); var cosPhi2 = Math.Cos(Phi + dPhi / 2); var sinPhi2 = Math.Sin(Phi + dPhi / 2); pt.push(-h / 2); pt.push((float)(cosPhi * r1)); pt.push((float)(sinPhi * r1)); // points nt.push(Nx); nt.push((float)(Ny * cosPhi)); nt.push((float)(Ny * sinPhi)); // normals pt.push(h / 2); pt.push((float)(cosPhi2 * r2)); pt.push((float)(sinPhi2 * r2)); // points nt.push(Nx); nt.push((float)(Ny * cosPhi2)); nt.push((float)(Ny * sinPhi2)); // normals Phi += dPhi; } var posLoc = gl.getAttribLocation(prog, "aPos"); gl.enableVertexAttribArray((uint)posLoc); gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer()); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(pt.ToArray()), gl.STATIC_DRAW); gl.vertexAttribPointer((uint)posLoc, 3, gl.FLOAT, false, 0, 0); var normLoc = gl.getAttribLocation(prog, "aNorm"); gl.enableVertexAttribArray((uint)normLoc); gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer()); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(nt), gl.STATIC_DRAW); gl.vertexAttribPointer((uint)normLoc, 3, gl.FLOAT, false, 0, 0); var prMatrix = new CanvasMatrix4(); gl.uniformMatrix4fv(gl.getUniformLocation(prog, "prMatrix"), false, new Float32Array(prMatrix.getAsArray())); var mvMatrix = new CanvasMatrix4(); var rotMat = new CanvasMatrix4(); rotMat.makeIdentity(); rotMat.rotate(-40, 0, 1, 0); var mvMatLoc = gl.getUniformLocation(prog, "mvMatrix"); gl.enable(gl.DEPTH_TEST); gl.depthFunc(gl.LEQUAL); gl.clearDepth(1.0f); gl.clearColor(0, 0, .5f, 1); var xOffs = 0; var yOffs = 0; var drag = 0; var xRot = 0; var yRot = 0; var transl = -1.5f; Action drawScene = delegate { gl.uniformMatrix4fv(gl.getUniformLocation(prog, "prMatrix"), false, new Float32Array(prMatrix.getAsArray())); gl.viewport(0, 0, gl_viewportWidth, gl_viewportHeight); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); rotMat.rotate(xRot / 5, 1, 0, 0); rotMat.rotate(yRot / 5, 0, 1, 0); yRot = 0; xRot = 0; mvMatrix.load(rotMat); mvMatrix.translate(0, 0, transl); gl.uniformMatrix4fv(mvMatLoc, false, new Float32Array(mvMatrix.getAsArray())); gl.drawArrays(gl.TRIANGLE_STRIP, 0, 2 * nPhi); gl.flush(); }; #region IsDisposed var IsDisposed = false; this.Dispose = delegate { if (IsDisposed) return; IsDisposed = true; canvas.Orphanize(); }; #endregion #region requestFullscreen Native.Document.body.ondblclick += delegate { if (IsDisposed) return; // http://tutorialzine.com/2012/02/enhance-your-website-fullscreen-api/ Native.Document.body.requestFullscreen(); }; #endregion var c = 0; Native.window.onframe += delegate { if (IsDisposed) return; c++; xRot += 2; yRot += 3; Native.document.title = "" + c; drawScene(); //animate(); }; #region AtResize Action AtResize = delegate { gl_viewportWidth = Native.window.Width; gl_viewportHeight = Native.window.Height; prMatrix = new CanvasMatrix4(); prMatrix.perspective(45f, (f)gl_viewportWidth / (f)gl_viewportHeight, 1f, 100f); canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportHeight); canvas.width = gl_viewportWidth; canvas.height = gl_viewportHeight; }; Native.window.onresize += e => { AtResize(); }; AtResize(); #endregion }
/* Source: http://www.ibiblio.org/e-notes/webgl/models/ethanol.html * http://www.worldofmolecules.com/3D/dopamine_3d.htm */ /// <summary> /// This is a javascript application. /// </summary> /// <param name="page">HTML document rendered by the web server which can now be enhanced.</param> public Application(IDefault page = null) { var prMatrix = new CanvasMatrix4(); var gl_viewportWidth = 500; var gl_viewportHeight = 500; var gl = new WebGLRenderingContext(); var canvas = gl.canvas.AttachToDocument(); #region AtResize Action AtResize = delegate { gl_viewportWidth = Native.window.Width; gl_viewportHeight = Native.window.Height; prMatrix = new CanvasMatrix4(); prMatrix.perspective(45f, (f)Native.window.aspect, 1f, 100f); canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportHeight); canvas.width = gl_viewportWidth; canvas.height = gl_viewportHeight; }; Native.window.onresize += e => { AtResize(); }; AtResize(); #endregion Native.document.body.style.overflow = IStyle.OverflowEnum.hidden; var h = 1f; var r1 = .5f; var r2 = .2f; #region requestPointerLock var __pointer_x = 0; var __pointer_y = 0; canvas.onmousedown += delegate { canvas.requestPointerLock(); }; canvas.onmousemove += e => { if (Native.Document.pointerLockElement == canvas) { __pointer_x += e.movementX; __pointer_y += e.movementY; } }; canvas.onmouseup += delegate { //Native.Document.exitPointerLock(); }; #endregion var prog = gl.createProgram( new GeometryVertexShader(), new GeometryFragmentShader() ); gl.linkProgram(prog); gl.useProgram(prog); var uniforms = prog.Uniforms(gl); var nPhi = 100; var nTheta = 50; var dPhi = 2 * Math.PI / nPhi; var dTheta = Math.PI / nTheta; var vertices = new IArray<float>(); var ind = new IArray<ushort>(); for (var j = 0; j <= nTheta; j++) { var Theta = j * dTheta; var cosTheta = Math.Cos(Theta); var sinTheta = Math.Sin(Theta); for (var i = 0; i <= nPhi; i++) { var Phi = i * dPhi; var cosPhi = Math.Cos(Phi); var sinPhi = Math.Sin(Phi); vertices.push((f)(cosPhi * sinTheta)); vertices.push((f)(-sinPhi * sinTheta)); vertices.push((f)(cosTheta)); } } for (var j = 0; j < nTheta; j++) for (var i = 0; i <= nPhi; i++) { ind.push((ushort)(j * (nPhi + 1) + i)); ind.push((ushort)((j + 1) * (nPhi + 1) + i)); } var posLocation = gl.getAttribLocation(prog, "aPos"); gl.enableVertexAttribArray((uint)posLocation); var posBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, posBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); gl.vertexAttribPointer((uint)posLocation, 3, gl.FLOAT, false, 0, 0); var indexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(ind.ToArray()), gl.STATIC_DRAW); //prMatrix.perspective(45, 1, .1, 100); gl.uniformMatrix4fv(gl.getUniformLocation(prog, "prMatrix"), false, new Float32Array(prMatrix.getAsArray())); var mvMatrix = new CanvasMatrix4(); var mvMatLoc = gl.getUniformLocation(prog, "mvMatrix"); gl.enable(gl.DEPTH_TEST); gl.depthFunc(gl.LEQUAL); gl.clearDepth(1.0f); gl.clearColor(0, 0, .8f, 1f); var xOffs = 0; var yOffs = 0; var drag = 0; var xRot = 0f; var yRot = 1f; var transl = -15.5f; #region drawScene Action drawScene = delegate { var rotMat = new CanvasMatrix4(); rotMat.makeIdentity(); #region draw Action<f, f, f, f, f, f, f> drawBall = (x, y, z, r, g, b, _scale) => { var scale = _scale * 1.4f; mvMatrix.makeIdentity(); mvMatrix.translate(x, y, z); mvMatrix.multRight(rotMat); mvMatrix.translate(0, 0, transl); gl.uniformMatrix4fv(mvMatLoc, false, new Float32Array(mvMatrix.getAsArray())); //var colorLoc = gl.getUniformLocation(prog, "color"); //var scaleLoc = gl.getUniformLocation(prog, "scale"); uniforms.color = new __vec3(r, g, b); uniforms.scale = scale; //gl.uniform1f(scaleLoc, scale); //gl.uniform3f(colorLoc, r, g, b); for (var i = 0; i < nTheta; i++) gl.drawElements(gl.TRIANGLE_STRIP, 2 * (nPhi + 1), gl.UNSIGNED_SHORT, 4 * (nPhi + 1) * i); }; Action<f, f, f, f> drawBall_white = (x, y, z, _scale) => drawBall(x, y, z, 1, 1, 1, _scale); Action<f, f, f, f> drawBall_red = (x, y, z, _scale) => drawBall(x, y, z, 1, 0, 0, _scale); Action<f, f, f, f> drawBall_blue = (x, y, z, _scale) => drawBall(x, y, z, 0, 0, 1, _scale); Action<f, f, f, f> drawBall_gray = (x, y, z, _scale) => drawBall(x, y, z, .3f, .3f, .3f, _scale); #endregion gl.viewport(0, 0, gl_viewportWidth, gl_viewportHeight); #region prMatrix gl.uniformMatrix4fv(gl.getUniformLocation(prog, "prMatrix"), false, new Float32Array(prMatrix.getAsArray())); #endregion gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); rotMat.rotate(xRot / 3, 1, 0, 0); rotMat.rotate(yRot / 3, 0, 1, 0); //yRot = 0; //xRot = 0; rotMat.rotate(__pointer_y * 1.0f, 1, 0, 0); rotMat.rotate(__pointer_x * 1.0f, 0, 1, 0); //__pointer_x = 0; //__pointer_y = 0; //http://en.wikipedia.org/wiki/Cyanogen #region C2N2 drawBall_blue(0, -3, 0, 1f); drawBall_gray(0, -1, 0, 1.2f); drawBall_gray(0, 1, 0, 1.2f); drawBall_blue(0, 3, 0, 1f); #endregion //#region C6H3 //drawBall_gray(2, -1, 0, 1.5f); //drawBall_gray(0, -2, 0, 1.5f); //drawBall_white(0, -3.5f, 0, 1f); //drawBall_gray(-2, -1, 0, 1.5f); //drawBall_gray(2, 1, 0, 1.5f); //drawBall_white(3 + 0.5f, 1.5f + 0.5f, 0, 1f); //drawBall_gray(0, 2, 0, 1.5f); //drawBall_white(0, 3.5f, 0, 1f); //drawBall_gray(-2, 1, 0, 1.5f); //#endregion //#region CH2-CH2 //drawBall_white(6, -1 + 1, -1.5f, 1f); //drawBall_gray(6, -1, 0, 1.5f); //drawBall_white(6, -1 + 1, 1.5f, 1f); //drawBall_white(4, -2 - 1, -1.5f, 1f); //drawBall_gray(4, -2, 0, 1.5f); //drawBall_white(4, -2 - 1, 1.5f, 1f); //#endregion //#region NH2 //drawBall_white(8, -2 - 1, -1.5f, 1f); //drawBall_blue(8, -2, 0, 1.5f); //drawBall_white(8, -2 - 1, 1.5f, 1f); //#endregion gl.flush(); }; #endregion #region mouse canvas.onmousedown += ev => { ev.preventDefault(); drag = 1; xOffs = ev.CursorX; yOffs = ev.CursorY; }; canvas.onmouseup += ev => { ev.preventDefault(); drag = 0; xOffs = ev.CursorX; yOffs = ev.CursorY; }; canvas.onmousemove += ev => { if (drag == 0) return; ev.preventDefault(); if (ev.shiftKey) { transl *= 1 + (ev.CursorY - yOffs) / 1000; yRot = -xOffs + ev.CursorX; } else { yRot = -xOffs + ev.CursorX; xRot = -yOffs + ev.CursorY; } xOffs = ev.CursorX; yOffs = ev.CursorY; drawScene(); }; #endregion #region onmousewheel canvas.onmousewheel += ev => { var del = 1.1f; if (ev.shiftKey) del = 1.01f; if (ev.WheelDirection > 0) transl *= del; else transl *= (1 / del); drawScene(); ev.PreventDefault(); }; #endregion #region IsDisposed var IsDisposed = false; this.Dispose = delegate { if (IsDisposed) return; IsDisposed = true; canvas.Orphanize(); }; #endregion #region requestFullscreen Native.Document.body.ondblclick += delegate { if (IsDisposed) return; // http://tutorialzine.com/2012/02/enhance-your-website-fullscreen-api/ Native.Document.body.requestFullscreen(); }; #endregion var c = 0; Native.window.onframe += delegate { if (IsDisposed) return; c++; xRot += 0.2f; yRot += 0.3f; drawScene(); }; //new IHTMLAnchor { "drag me to my.jsc-solutions.net" }.AttachToDocument().With( // dragme => // { // dragme.style.position = IStyle.PositionEnum.@fixed; // dragme.style.left = "1em"; // dragme.style.bottom = "1em"; // dragme.AllowToDragAsApplicationPackage(); // } //); }
/// <summary> /// This is a javascript application. /// </summary> /// <param name="page">HTML document rendered by the web server which can now be enhanced.</param> public Application(IDefault page = null) { var gl_viewportWidth = 500; var gl_viewportHeight = 500; var gl = new WebGLRenderingContext(); #region canvas var canvas = gl.canvas.AttachToDocument(); Native.document.body.style.overflow = IStyle.OverflowEnum.hidden; canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportHeight); canvas.width = gl_viewportWidth; canvas.height = gl_viewportHeight; #endregion var h = 1f; var r1 = .5f; var r2 = .2f; var nPhi = 500; var prog = gl.createProgram(); #region createShader Func <ScriptCoreLib.GLSL.Shader, WebGLShader> createShader = (src) => { var shader = gl.createShader(src); // verify if (gl.getShaderParameter(shader, gl.COMPILE_STATUS) == null) { Native.window.alert("error in SHADER:\n" + gl.getShaderInfoLog(shader)); throw new InvalidOperationException("shader failed"); } return(shader); }; #endregion var vs = createShader(new GeometryVertexShader()); var fs = createShader(new GeometryFragmentShader()); gl.attachShader(prog, vs); gl.attachShader(prog, fs); gl.linkProgram(prog); gl.useProgram(prog); var pt = new IArray <float>(); var nt = new IArray <float>(); var Phi = 0.0; var dPhi = 2 * Math.PI / (nPhi - 1); var Nx = r1 - r2; var Ny = h; var N = (float)Math.Sqrt(Nx * Nx + Ny * Ny); Nx /= N; Ny /= N; for (var i = 0; i < nPhi; i++) { var cosPhi = Math.Cos(Phi); var sinPhi = Math.Sin(Phi); var cosPhi2 = Math.Cos(Phi + dPhi / 2); var sinPhi2 = Math.Sin(Phi + dPhi / 2); pt.push(-h / 2); pt.push((float)(cosPhi * r1)); pt.push((float)(sinPhi * r1)); // points nt.push(Nx); nt.push((float)(Ny * cosPhi)); nt.push((float)(Ny * sinPhi)); // normals pt.push(h / 2); pt.push((float)(cosPhi2 * r2)); pt.push((float)(sinPhi2 * r2)); // points nt.push(Nx); nt.push((float)(Ny * cosPhi2)); nt.push((float)(Ny * sinPhi2)); // normals Phi += dPhi; } var posLoc = gl.getAttribLocation(prog, "aPos"); gl.enableVertexAttribArray((uint)posLoc); gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer()); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(pt.ToArray()), gl.STATIC_DRAW); gl.vertexAttribPointer((uint)posLoc, 3, gl.FLOAT, false, 0, 0); var normLoc = gl.getAttribLocation(prog, "aNorm"); gl.enableVertexAttribArray((uint)normLoc); gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer()); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(nt), gl.STATIC_DRAW); gl.vertexAttribPointer((uint)normLoc, 3, gl.FLOAT, false, 0, 0); var prMatrix = new CanvasMatrix4(); gl.uniformMatrix4fv(gl.getUniformLocation(prog, "prMatrix"), false, new Float32Array(prMatrix.getAsArray())); var mvMatrix = new CanvasMatrix4(); var rotMat = new CanvasMatrix4(); rotMat.makeIdentity(); rotMat.rotate(-40, 0, 1, 0); var mvMatLoc = gl.getUniformLocation(prog, "mvMatrix"); gl.enable(gl.DEPTH_TEST); gl.depthFunc(gl.LEQUAL); gl.clearDepth(1.0f); gl.clearColor(0, 0, .5f, 1); var xOffs = 0; var yOffs = 0; var drag = 0; var xRot = 0; var yRot = 0; var transl = -1.5f; Action drawScene = delegate { gl.uniformMatrix4fv(gl.getUniformLocation(prog, "prMatrix"), false, new Float32Array(prMatrix.getAsArray())); gl.viewport(0, 0, gl_viewportWidth, gl_viewportHeight); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); rotMat.rotate(xRot / 5, 1, 0, 0); rotMat.rotate(yRot / 5, 0, 1, 0); yRot = 0; xRot = 0; mvMatrix.load(rotMat); mvMatrix.translate(0, 0, transl); gl.uniformMatrix4fv(mvMatLoc, false, new Float32Array(mvMatrix.getAsArray())); gl.drawArrays(gl.TRIANGLE_STRIP, 0, 2 * nPhi); gl.flush(); }; #region IsDisposed var IsDisposed = false; this.Dispose = delegate { if (IsDisposed) { return; } IsDisposed = true; canvas.Orphanize(); }; #endregion #region requestFullscreen Native.Document.body.ondblclick += delegate { if (IsDisposed) { return; } // http://tutorialzine.com/2012/02/enhance-your-website-fullscreen-api/ Native.Document.body.requestFullscreen(); }; #endregion var c = 0; Native.window.onframe += delegate { if (IsDisposed) { return; } c++; xRot += 2; yRot += 3; Native.document.title = "" + c; drawScene(); //animate(); }; #region AtResize Action AtResize = delegate { gl_viewportWidth = Native.window.Width; gl_viewportHeight = Native.window.Height; prMatrix = new CanvasMatrix4(); prMatrix.perspective(45f, (f)gl_viewportWidth / (f)gl_viewportHeight, 1f, 100f); canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportHeight); canvas.width = gl_viewportWidth; canvas.height = gl_viewportHeight; }; Native.window.onresize += e => { AtResize(); }; AtResize(); #endregion }
/* Source: http://www.ibiblio.org/e-notes/webgl/models/ethanol.html * */ /// <summary> /// This is a javascript application. /// </summary> /// <param name="page">HTML document rendered by the web server which can now be enhanced.</param> public Application(IDefault page = null) { var gl_viewportWidth = 500; var gl_viewportHeight = 500; var gl = new WebGLRenderingContext(); var canvas = gl.canvas.AttachToDocument(); Native.document.body.style.overflow = IStyle.OverflowEnum.hidden; canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportHeight); canvas.width = gl_viewportWidth; canvas.height = gl_viewportHeight; var h = 1f; var r1 = .5f; var r2 = .2f; var prog = gl.createProgram(); #region createShader Func <ScriptCoreLib.GLSL.Shader, WebGLShader> createShader = (src) => { var shader = gl.createShader(src); // verify if (gl.getShaderParameter(shader, gl.COMPILE_STATUS) == null) { Native.window.alert("error in SHADER:\n" + gl.getShaderInfoLog(shader)); throw new InvalidOperationException("shader failed"); } return(shader); }; #endregion var vs = createShader(new GeometryVertexShader()); var fs = createShader(new GeometryFragmentShader()); gl.attachShader(prog, vs); gl.attachShader(prog, fs); gl.linkProgram(prog); gl.useProgram(prog); var nPhi = 100; var nTheta = 50; var dPhi = 2 * Math.PI / nPhi; var dTheta = Math.PI / nTheta; var vertices = new IArray <float>(); var ind = new IArray <ushort>(); for (var j = 0; j <= nTheta; j++) { var Theta = j * dTheta; var cosTheta = Math.Cos(Theta); var sinTheta = Math.Sin(Theta); for (var i = 0; i <= nPhi; i++) { var Phi = i * dPhi; var cosPhi = Math.Cos(Phi); var sinPhi = Math.Sin(Phi); vertices.push((f)(cosPhi * sinTheta)); vertices.push((f)(-sinPhi * sinTheta)); vertices.push((f)(cosTheta)); } } for (var j = 0; j < nTheta; j++) { for (var i = 0; i <= nPhi; i++) { ind.push((ushort)(j * (nPhi + 1) + i)); ind.push((ushort)((j + 1) * (nPhi + 1) + i)); } } var posLocation = gl.getAttribLocation(prog, "aPos"); gl.enableVertexAttribArray((uint)posLocation); var posBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, posBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); gl.vertexAttribPointer((uint)posLocation, 3, gl.FLOAT, false, 0, 0); var indexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(ind.ToArray()), gl.STATIC_DRAW); var prMatrix = new CanvasMatrix4(); //prMatrix.perspective(45, 1, .1, 100); gl.uniformMatrix4fv(gl.getUniformLocation(prog, "prMatrix"), false, new Float32Array(prMatrix.getAsArray())); var mvMatrix = new CanvasMatrix4(); var rotMat = new CanvasMatrix4(); rotMat.makeIdentity(); var mvMatLoc = gl.getUniformLocation(prog, "mvMatrix"); var colorLoc = gl.getUniformLocation(prog, "color"); var scaleLoc = gl.getUniformLocation(prog, "scale"); gl.enable(gl.DEPTH_TEST); gl.depthFunc(gl.LEQUAL); gl.clearDepth(1.0f); gl.clearColor(0, 0, .8f, 1f); var xOffs = 0; var yOffs = 0; var drag = 0; var xRot = 0f; var yRot = 0f; var transl = -10.5f; #region drawBall Action <f, f, f, f, f, f, f> drawBall = (x, y, z, r, g, b, _scale) => { var scale = _scale * 1f; mvMatrix.makeIdentity(); mvMatrix.translate(x, y, z); mvMatrix.multRight(rotMat); mvMatrix.translate(0, 0, transl); gl.uniformMatrix4fv(mvMatLoc, false, new Float32Array(mvMatrix.getAsArray())); gl.uniform1f(scaleLoc, scale); gl.uniform3f(colorLoc, r, g, b); for (var i = 0; i < nTheta; i++) { gl.drawElements(gl.TRIANGLE_STRIP, 2 * (nPhi + 1), gl.UNSIGNED_SHORT, 4 * (nPhi + 1) * i); } }; #endregion Action <f, f, f, f> drawBall_white = (x, y, z, _scale) => drawBall(x, y, z, 1, 1, 1, _scale); Action <f, f, f, f> drawBall_red = (x, y, z, _scale) => drawBall(x, y, z, 1, 0, 0, _scale); #region drawScene Action drawScene = delegate { gl.viewport(0, 0, gl_viewportWidth, gl_viewportHeight); #region prMatrix gl.uniformMatrix4fv(gl.getUniformLocation(prog, "prMatrix"), false, new Float32Array(prMatrix.getAsArray())); #endregion gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); rotMat.rotate(xRot / 3, 1, 0, 0); rotMat.rotate(yRot / 3, 0, 1, 0); yRot = 0; xRot = 0; drawBall(0, 0, 0, .3f, .3f, .3f, 1.5f); drawBall(1, 1, 1, .3f, .3f, .3f, 1.5f); drawBall_white(2, 2, 0, 1); drawBall_white(2, 0, 2, 1); drawBall_white(0, 2, 2, 1); drawBall_white(-1, -1, 1, 1); drawBall_white(1, -1, -1, 1); drawBall_red(-1, 1, -1, 1.5f); drawBall_white(-2, 0, -2, 1); gl.flush(); }; #endregion #region mouse canvas.onmousedown += ev => { ev.PreventDefault(); drag = 1; xOffs = ev.CursorX; yOffs = ev.CursorY; }; canvas.onmouseup += ev => { ev.PreventDefault(); drag = 0; xOffs = ev.CursorX; yOffs = ev.CursorY; }; canvas.onmousemove += ev => { if (drag == 0) { return; } ev.PreventDefault(); if (ev.shiftKey) { transl *= 1 + (ev.CursorY - yOffs) / 1000; yRot = -xOffs + ev.CursorX; } else { yRot = -xOffs + ev.CursorX; xRot = -yOffs + ev.CursorY; } xOffs = ev.CursorX; yOffs = ev.CursorY; drawScene(); }; #endregion #region onmousewheel canvas.onmousewheel += ev => { var del = 1.1f; if (ev.shiftKey) { del = 1.01f; } if (ev.WheelDirection > 0) { transl *= del; } else { transl *= (1 / del); } drawScene(); ev.PreventDefault(); }; #endregion #region IsDisposed var IsDisposed = false; this.Dispose = delegate { if (IsDisposed) { return; } IsDisposed = true; canvas.Orphanize(); }; #endregion #region requestFullscreen Native.Document.body.ondblclick += delegate { if (IsDisposed) { return; } // http://tutorialzine.com/2012/02/enhance-your-website-fullscreen-api/ Native.Document.body.requestFullscreen(); }; #endregion var c = 0; Native.window.onframe += delegate { if (IsDisposed) { return; } c++; xRot += 0.2f; yRot += 0.3f; drawScene(); }; #region AtResize Action AtResize = delegate { gl_viewportWidth = Native.window.Width; gl_viewportHeight = Native.window.Height; prMatrix = new CanvasMatrix4(); prMatrix.perspective(45f, (f)Native.window.aspect, 1f, 100f); canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportHeight); canvas.width = gl_viewportWidth; canvas.height = gl_viewportHeight; }; Native.window.onresize += e => { AtResize(); }; AtResize(); #endregion new IHTMLAnchor { "drag me to my.jsc-solutions.net" }.AttachToDocument().With( dragme => { dragme.style.position = IStyle.PositionEnum.@fixed; dragme.style.left = "1em"; dragme.style.bottom = "1em"; dragme.AllowToDragAsApplicationPackage(); } ); }
/// <summary> /// This is a javascript application. /// </summary> /// <param name="page">HTML document rendered by the web server which can now be enhanced.</param> public Application(IDefault page = null) { var gl_viewportWidth = Native.window.Width; var gl_viewportHeight = Native.window.Height; var gl = new WebGLRenderingContext(); var canvas = gl.canvas.AttachToDocument(); Native.document.body.style.overflow = IStyle.OverflowEnum.hidden; canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportWidth); gl.viewport(0, 0, gl_viewportWidth, gl_viewportWidth); var prog = gl.createProgram( new CubicVertexShader(), new CubicFragmentShader() ); var posLoc = 0U; gl.bindAttribLocation(prog, posLoc, "aPos"); var normLoc = 1U; gl.bindAttribLocation(prog, normLoc, "aNorm"); gl.linkProgram(prog); gl.useProgram(prog); #region data var a = 1.0f; // where is it used? what shall be the type? var pt0 = new float[] {-a,-a,a, a,-a,a, -a,a,a, a,a,a, // cubic -a,a,a, a,a,a, -a,a,-a, a,a,-a, -a,a,-a, a,a,-a, -a,-a,-a, a,-a,-a, -a,-a,-a, a,-a,-a, -a,-a,a, a,-a,a, a,a,a, a,a,-a, a,-a,a, a,-a,-a, -a,a,a, -a,a,-a, -a,-a,a, -a,-a,-a}; var nt = new float[] {0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,-1, 0,0,-1, 0,0,-1, 0,0,-1, 0,-1,0, 0,-1,0, 0,-1,0, 0,-1,0, 1,0,0, 1,0,0, 1,0,0, 1,0,0, -1,0,0, -1,0,0, -1,0,0, -1,0,0}; var ind = new ushort[] {0,1,2,1,2,3, 4,5,6,5,6,7, 8,9,10,9,10,11, 12,13,14,13,14,15, 16,17,18,17,18,19, 20,21,22,21,22,23}; var nPhi = 25; var nTheta = 12; var r = .15; var dPhi = 2.0 * Math.PI / nPhi; var dTheta = Math.PI / nTheta; for (var j = 0; j <= nTheta; j++) { var Theta = j * dTheta; var cosTheta = Math.Cos(Theta); var sinTheta = Math.Sin(Theta); for (var i = 0; i <= nPhi; i++) { var Phi = i * dPhi; var cosPhi = Math.Cos(Phi); var sinPhi = Math.Sin(Phi); ((IArray<float>)(object)pt0).push((float)(r * cosPhi * sinTheta)); ((IArray<float>)(object)pt0).push((float)(-r * sinPhi * sinTheta)); ((IArray<float>)(object)pt0).push((float)(r * cosTheta)); ((IArray<float>)(object)nt).push((float)(cosPhi * sinTheta)); ((IArray<float>)(object)nt).push((float)(-sinPhi * sinTheta)); ((IArray<float>)(object)nt).push((float)(cosTheta)); } } var n1 = nPhi + 1; var off = 24; for (var i = 0; i < nTheta; i++) for (var j = 0; j < nPhi; j++) { ((IArray<int>)(object)ind).push(i * n1 + j + off); ((IArray<int>)(object)ind).push((i + 1) * n1 + j + 1 + off); ((IArray<int>)(object)ind).push(i * n1 + j + 1 + off); ((IArray<int>)(object)ind).push(i * n1 + j + off); ((IArray<int>)(object)ind).push((i + 1) * n1 + j + off); ((IArray<int>)(object)ind).push((i + 1) * n1 + j + 1 + off); } #endregion gl.enableVertexAttribArray(posLoc); gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer()); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(pt0), gl.STATIC_DRAW); gl.vertexAttribPointer(posLoc, 3, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(normLoc); gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer()); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(nt), gl.STATIC_DRAW); gl.vertexAttribPointer(normLoc, 3, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.createBuffer()); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(ind), gl.STATIC_DRAW); var prMatrix = new CanvasMatrix4(); prMatrix.perspective(45f, 1f, .1f, 100f); gl.uniformMatrix4fv(gl.getUniformLocation(prog, "prMatrix"), false, new Float32Array(prMatrix.getAsArray())); var mvMatrix = new CanvasMatrix4(); var rotMat = new CanvasMatrix4(); rotMat.makeIdentity(); rotMat.rotate(25, 1, 1, 0); var mvMatLoc = gl.getUniformLocation(prog, "mvMatrix"); var colorLoc = gl.getUniformLocation(prog, "u_color"); var line_prog = gl.createProgram( new LineVertexShader(), new LineFragmentShader() ); var lineLoc = 2U; gl.bindAttribLocation(line_prog, lineLoc, "aPos"); gl.linkProgram(line_prog); gl.useProgram(line_prog); gl.uniformMatrix4fv(gl.getUniformLocation(line_prog, "prMatrix"), false, new Float32Array(prMatrix.getAsArray())); var mvMatLineLoc = gl.getUniformLocation(line_prog, "mvMatrix"); var pt1 = new float[]{2,1,1, -2,1,1, 2,-1,1, -2,-1,1, 2,1,-1, -2,1,-1, 2,-1,-1, -2,-1,-1, 1,2,1, 1,-2,1, 1,2,-1, 1,-2,-1, -1,2,1, -1,-2,1, -1,2,-1, -1,-2,-1, 1,1,2, 1,1,-2, -1,1,2, -1,1,-2, 1,-1,2, 1,-1,-2, -1,-1,2, -1,-1,-2 }; gl.enableVertexAttribArray(lineLoc); gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer()); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(pt1), gl.STATIC_DRAW); gl.vertexAttribPointer(lineLoc, 3, gl.FLOAT, false, 0, 0); gl.enable(gl.DEPTH_TEST); gl.depthFunc(gl.LEQUAL); gl.clearDepth(1.0f); gl.clearColor(.5f, 1f, .5f, 1f); gl.lineWidth(2); var xOffs = 0; var yOffs = 0; var drag = 0; var xRot = 0f; var yRot = 0f; var transl = -6.0f; #region drawBall Action<f, f, f> drawBall = (x, y, z) => { mvMatrix.makeIdentity(); mvMatrix.translate(x, y, z); mvMatrix.multRight(rotMat); mvMatrix.translate(0, 0, transl); gl.uniformMatrix4fv(mvMatLoc, false, new Float32Array(mvMatrix.getAsArray())); gl.drawElements(gl.TRIANGLES, 6 * nPhi * nTheta, gl.UNSIGNED_SHORT, 72); }; #endregion #region drawScene Action drawScene = delegate { gl.viewport(0, 0, gl_viewportWidth, gl_viewportWidth); gl.useProgram(prog); gl.uniformMatrix4fv(gl.getUniformLocation(prog, "prMatrix"), false, new Float32Array(prMatrix.getAsArray())); rotMat.rotate(xRot / 5, 1, 0, 0); rotMat.rotate(yRot / 5, 0, 1, 0); yRot = 0; xRot = 0; gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); gl.uniform4f(colorLoc, 1, 1, 0, 1); drawBall(1, 1, 1); drawBall(-1, 1, 1); drawBall(1, -1, 1); drawBall(1, 1, -1); drawBall(-1, -1, 1); drawBall(-1, 1, -1); drawBall(1, -1, -1); drawBall(-1, -1, -1); mvMatrix.load(rotMat); mvMatrix.translate(0, 0, transl); gl.uniformMatrix4fv(mvMatLoc, false, new Float32Array(mvMatrix.getAsArray())); gl.enable(gl.BLEND); gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); gl.uniform4f(colorLoc, .0f, .0f, .9f, .7f); gl.depthMask(false); gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_SHORT, 0); gl.depthMask(true); gl.disable(gl.BLEND); gl.useProgram(line_prog); gl.uniformMatrix4fv(gl.getUniformLocation(line_prog, "prMatrix"), false, new Float32Array(prMatrix.getAsArray())); gl.uniformMatrix4fv(mvMatLineLoc, false, new Float32Array(mvMatrix.getAsArray())); gl.drawArrays(gl.LINES, 0, 24); gl.flush(); }; #endregion drawScene(); #region AtResize Action AtResize = delegate { gl_viewportWidth = Native.window.Width; gl_viewportHeight = Native.window.Height; prMatrix = new CanvasMatrix4(); //var aspect = (f)gl_viewportWidth / (f)gl_viewportHeight; var aspect = Native.window.aspect; Console.WriteLine( new { gl_viewportWidth, gl_viewportHeight, aspect } ); //Native.document.title = new { aspect }.ToString(); prMatrix.perspective(45f, (f)aspect, 1f, 100f); canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportHeight); canvas.width = gl_viewportWidth; canvas.height = gl_viewportHeight; drawScene(); }; AtResize(); Native.window.onresize += delegate { AtResize(); }; #endregion #region mouse canvas.onmousedown += ev => { ev.PreventDefault(); drag = 1; xOffs = ev.CursorX; yOffs = ev.CursorY; canvas.requestPointerLock(); }; canvas.onmouseup += ev => { ev.PreventDefault(); drag = 0; xOffs = ev.CursorX; yOffs = ev.CursorY; Native.Document.exitPointerLock(); }; canvas.onmousemove += ev => { if (drag == 0) return; if (Native.Document.pointerLockElement == canvas) { xRot += ev.movementY; yRot += ev.movementX; drawScene(); return; } ev.PreventDefault(); if (ev.shiftKey) { transl *= 1 + (ev.CursorY - yOffs) / 1000; yRot = -xOffs + ev.CursorX; } else { yRot = -xOffs + ev.CursorX; xRot = -yOffs + ev.CursorY; } xOffs = ev.CursorX; yOffs = ev.CursorY; drawScene(); }; #endregion #region onmousewheel canvas.onmousewheel += ev => { var del = 1.1f; if (ev.shiftKey) del = 1.01f; if (ev.WheelDirection > 0) transl *= del; else transl *= (1 / del); drawScene(); ev.PreventDefault(); }; #endregion #region IsDisposed var IsDisposed = false; this.Dispose = delegate { if (IsDisposed) return; IsDisposed = true; canvas.Orphanize(); }; #endregion #region requestFullscreen Native.Document.body.ondblclick += delegate { if (IsDisposed) return; // http://tutorialzine.com/2012/02/enhance-your-website-fullscreen-api/ canvas.requestFullscreen(); }; #endregion #region tick Native.window.onframe += delegate { if (IsDisposed) return; if (drag == 0) { xRot += 2; yRot += 3; } drawScene(); //animate(); }; #endregion //Native.Document.body.style.backgroundColor = Color.FromRGB(0x80, 0xFF, 0x80); }
/* Source: http://www.ibiblio.org/e-notes/webgl/models/ethanol.html * */ /// <summary> /// This is a javascript application. /// </summary> /// <param name="page">HTML document rendered by the web server which can now be enhanced.</param> public Application(IDefault page = null) { var gl_viewportWidth = 500; var gl_viewportHeight = 500; var gl = new WebGLRenderingContext(); var canvas = gl.canvas.AttachToDocument(); Native.document.body.style.overflow = IStyle.OverflowEnum.hidden; canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportHeight); canvas.width = gl_viewportWidth; canvas.height = gl_viewportHeight; var h = 1f; var r1 = .5f; var r2 = .2f; var prog = gl.createProgram(); #region createShader Func<ScriptCoreLib.GLSL.Shader, WebGLShader> createShader = (src) => { var shader = gl.createShader(src); // verify if (gl.getShaderParameter(shader, gl.COMPILE_STATUS) == null) { Native.window.alert("error in SHADER:\n" + gl.getShaderInfoLog(shader)); throw new InvalidOperationException("shader failed"); } return shader; }; #endregion var vs = createShader(new GeometryVertexShader()); var fs = createShader(new GeometryFragmentShader()); gl.attachShader(prog, vs); gl.attachShader(prog, fs); gl.linkProgram(prog); gl.useProgram(prog); var nPhi = 100; var nTheta = 50; var dPhi = 2 * Math.PI / nPhi; var dTheta = Math.PI / nTheta; var vertices = new IArray<float>(); var ind = new IArray<ushort>(); for (var j = 0; j <= nTheta; j++) { var Theta = j * dTheta; var cosTheta = Math.Cos(Theta); var sinTheta = Math.Sin(Theta); for (var i = 0; i <= nPhi; i++) { var Phi = i * dPhi; var cosPhi = Math.Cos(Phi); var sinPhi = Math.Sin(Phi); vertices.push((f)(cosPhi * sinTheta)); vertices.push((f)(-sinPhi * sinTheta)); vertices.push((f)(cosTheta)); } } for (var j = 0; j < nTheta; j++) for (var i = 0; i <= nPhi; i++) { ind.push((ushort)(j * (nPhi + 1) + i)); ind.push((ushort)((j + 1) * (nPhi + 1) + i)); } var posLocation = gl.getAttribLocation(prog, "aPos"); gl.enableVertexAttribArray((uint)posLocation); var posBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, posBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); gl.vertexAttribPointer((uint)posLocation, 3, gl.FLOAT, false, 0, 0); var indexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(ind.ToArray()), gl.STATIC_DRAW); var prMatrix = new CanvasMatrix4(); //prMatrix.perspective(45, 1, .1, 100); gl.uniformMatrix4fv(gl.getUniformLocation(prog, "prMatrix"), false, new Float32Array(prMatrix.getAsArray())); var mvMatrix = new CanvasMatrix4(); var rotMat = new CanvasMatrix4(); rotMat.makeIdentity(); var mvMatLoc = gl.getUniformLocation(prog, "mvMatrix"); var colorLoc = gl.getUniformLocation(prog, "color"); var scaleLoc = gl.getUniformLocation(prog, "scale"); gl.enable(gl.DEPTH_TEST); gl.depthFunc(gl.LEQUAL); gl.clearDepth(1.0f); gl.clearColor(0, 0, .8f, 1f); var xOffs = 0; var yOffs = 0; var drag = 0; var xRot = 0f; var yRot = 0f; var transl = -10.5f; #region drawBall Action<f, f, f, f, f, f, f> drawBall = (x, y, z, r, g, b, _scale) => { var scale = _scale * 1f; mvMatrix.makeIdentity(); mvMatrix.translate(x, y, z); mvMatrix.multRight(rotMat); mvMatrix.translate(0, 0, transl); gl.uniformMatrix4fv(mvMatLoc, false, new Float32Array(mvMatrix.getAsArray())); gl.uniform1f(scaleLoc, scale); gl.uniform3f(colorLoc, r, g, b); for (var i = 0; i < nTheta; i++) gl.drawElements(gl.TRIANGLE_STRIP, 2 * (nPhi + 1), gl.UNSIGNED_SHORT, 4 * (nPhi + 1) * i); }; #endregion Action<f, f, f, f> drawBall_white = (x, y, z, _scale) => drawBall(x, y, z, 1, 1, 1, _scale); Action<f, f, f, f> drawBall_red = (x, y, z, _scale) => drawBall(x, y, z, 1, 0, 0, _scale); #region drawScene Action drawScene = delegate { gl.viewport(0, 0, gl_viewportWidth, gl_viewportHeight); #region prMatrix gl.uniformMatrix4fv(gl.getUniformLocation(prog, "prMatrix"), false, new Float32Array(prMatrix.getAsArray())); #endregion gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); rotMat.rotate(xRot / 3, 1, 0, 0); rotMat.rotate(yRot / 3, 0, 1, 0); yRot = 0; xRot = 0; drawBall(0, 0, 0, .3f, .3f, .3f, 1.5f); drawBall(1, 1, 1, .3f, .3f, .3f, 1.5f); drawBall_white(2, 2, 0, 1); drawBall_white(2, 0, 2, 1); drawBall_white(0, 2, 2, 1); drawBall_white(-1, -1, 1, 1); drawBall_white(1, -1, -1, 1); drawBall_red(-1, 1, -1, 1.5f); drawBall_white(-2, 0, -2, 1); gl.flush(); }; #endregion #region mouse canvas.onmousedown += ev => { ev.PreventDefault(); drag = 1; xOffs = ev.CursorX; yOffs = ev.CursorY; }; canvas.onmouseup += ev => { ev.PreventDefault(); drag = 0; xOffs = ev.CursorX; yOffs = ev.CursorY; }; canvas.onmousemove += ev => { if (drag == 0) return; ev.PreventDefault(); if (ev.shiftKey) { transl *= 1 + (ev.CursorY - yOffs) / 1000; yRot = -xOffs + ev.CursorX; } else { yRot = -xOffs + ev.CursorX; xRot = -yOffs + ev.CursorY; } xOffs = ev.CursorX; yOffs = ev.CursorY; drawScene(); }; #endregion #region onmousewheel canvas.onmousewheel += ev => { var del = 1.1f; if (ev.shiftKey) del = 1.01f; if (ev.WheelDirection > 0) transl *= del; else transl *= (1 / del); drawScene(); ev.PreventDefault(); }; #endregion #region IsDisposed var IsDisposed = false; this.Dispose = delegate { if (IsDisposed) return; IsDisposed = true; canvas.Orphanize(); }; #endregion #region requestFullscreen Native.Document.body.ondblclick += delegate { if (IsDisposed) return; // http://tutorialzine.com/2012/02/enhance-your-website-fullscreen-api/ Native.Document.body.requestFullscreen(); }; #endregion var c = 0; Native.window.onframe += delegate { if (IsDisposed) return; c++; xRot += 0.2f; yRot += 0.3f; drawScene(); }; #region AtResize Action AtResize = delegate { gl_viewportWidth = Native.window.Width; gl_viewportHeight = Native.window.Height; prMatrix = new CanvasMatrix4(); prMatrix.perspective(45f, (f)Native.window.aspect, 1f, 100f); canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportHeight); canvas.width = gl_viewportWidth; canvas.height = gl_viewportHeight; }; Native.window.onresize += e => { AtResize(); }; AtResize(); #endregion new IHTMLAnchor { "drag me to my.jsc-solutions.net" }.AttachToDocument().With( dragme => { dragme.style.position = IStyle.PositionEnum.@fixed; dragme.style.left = "1em"; dragme.style.bottom = "1em"; dragme.AllowToDragAsApplicationPackage(); } ); }
/// <summary> /// This is a javascript application. /// </summary> /// <param name="page">HTML document rendered by the web server which can now be enhanced.</param> public Application(IDefault page = null) { var gl_viewportWidth = Native.window.Width; var gl_viewportHeight = Native.window.Height; var gl = new WebGLRenderingContext(); var canvas = gl.canvas.AttachToDocument(); Native.document.body.style.overflow = IStyle.OverflowEnum.hidden; canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportWidth); gl.viewport(0, 0, gl_viewportWidth, gl_viewportWidth); var prog = gl.createProgram( new CubicVertexShader(), new CubicFragmentShader() ); var posLoc = 0U; gl.bindAttribLocation(prog, posLoc, "aPos"); var normLoc = 1U; gl.bindAttribLocation(prog, normLoc, "aNorm"); gl.linkProgram(prog); gl.useProgram(prog); #region data var a = 1.0f; // where is it used? what shall be the type? var pt0 = new float[] { -a, -a, a, a, -a, a, -a, a, a, a, a, a, // cubic -a, a, a, a, a, a, -a, a, -a, a, a, -a, -a, a, -a, a, a, -a, -a, -a, -a, a, -a, -a, -a, -a, -a, a, -a, -a, -a, -a, a, a, -a, a, a, a, a, a, a, -a, a, -a, a, a, -a, -a, -a, a, a, -a, a, -a, -a, -a, a, -a, -a, -a }; var nt = new float[] { 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0 }; var ind = new ushort[] { 0, 1, 2, 1, 2, 3, 4, 5, 6, 5, 6, 7, 8, 9, 10, 9, 10, 11, 12, 13, 14, 13, 14, 15, 16, 17, 18, 17, 18, 19, 20, 21, 22, 21, 22, 23 }; var nPhi = 25; var nTheta = 12; var r = .15; var dPhi = 2.0 * Math.PI / nPhi; var dTheta = Math.PI / nTheta; for (var j = 0; j <= nTheta; j++) { var Theta = j * dTheta; var cosTheta = Math.Cos(Theta); var sinTheta = Math.Sin(Theta); for (var i = 0; i <= nPhi; i++) { var Phi = i * dPhi; var cosPhi = Math.Cos(Phi); var sinPhi = Math.Sin(Phi); ((IArray <float>)(object) pt0).push((float)(r * cosPhi * sinTheta)); ((IArray <float>)(object) pt0).push((float)(-r * sinPhi * sinTheta)); ((IArray <float>)(object) pt0).push((float)(r * cosTheta)); ((IArray <float>)(object) nt).push((float)(cosPhi * sinTheta)); ((IArray <float>)(object) nt).push((float)(-sinPhi * sinTheta)); ((IArray <float>)(object) nt).push((float)(cosTheta)); } } var n1 = nPhi + 1; var off = 24; for (var i = 0; i < nTheta; i++) { for (var j = 0; j < nPhi; j++) { ((IArray <int>)(object) ind).push(i * n1 + j + off); ((IArray <int>)(object) ind).push((i + 1) * n1 + j + 1 + off); ((IArray <int>)(object) ind).push(i * n1 + j + 1 + off); ((IArray <int>)(object) ind).push(i * n1 + j + off); ((IArray <int>)(object) ind).push((i + 1) * n1 + j + off); ((IArray <int>)(object) ind).push((i + 1) * n1 + j + 1 + off); } } #endregion gl.enableVertexAttribArray(posLoc); gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer()); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(pt0), gl.STATIC_DRAW); gl.vertexAttribPointer(posLoc, 3, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(normLoc); gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer()); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(nt), gl.STATIC_DRAW); gl.vertexAttribPointer(normLoc, 3, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.createBuffer()); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(ind), gl.STATIC_DRAW); var prMatrix = new CanvasMatrix4(); prMatrix.perspective(45f, 1f, .1f, 100f); gl.uniformMatrix4fv(gl.getUniformLocation(prog, "prMatrix"), false, new Float32Array(prMatrix.getAsArray())); var mvMatrix = new CanvasMatrix4(); var rotMat = new CanvasMatrix4(); rotMat.makeIdentity(); rotMat.rotate(25, 1, 1, 0); var mvMatLoc = gl.getUniformLocation(prog, "mvMatrix"); var colorLoc = gl.getUniformLocation(prog, "u_color"); var line_prog = gl.createProgram( new LineVertexShader(), new LineFragmentShader() ); var lineLoc = 2U; gl.bindAttribLocation(line_prog, lineLoc, "aPos"); gl.linkProgram(line_prog); gl.useProgram(line_prog); gl.uniformMatrix4fv(gl.getUniformLocation(line_prog, "prMatrix"), false, new Float32Array(prMatrix.getAsArray())); var mvMatLineLoc = gl.getUniformLocation(line_prog, "mvMatrix"); var pt1 = new float[] { 2, 1, 1, -2, 1, 1, 2, -1, 1, -2, -1, 1, 2, 1, -1, -2, 1, -1, 2, -1, -1, -2, -1, -1, 1, 2, 1, 1, -2, 1, 1, 2, -1, 1, -2, -1, -1, 2, 1, -1, -2, 1, -1, 2, -1, -1, -2, -1, 1, 1, 2, 1, 1, -2, -1, 1, 2, -1, 1, -2, 1, -1, 2, 1, -1, -2, -1, -1, 2, -1, -1, -2 }; gl.enableVertexAttribArray(lineLoc); gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer()); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(pt1), gl.STATIC_DRAW); gl.vertexAttribPointer(lineLoc, 3, gl.FLOAT, false, 0, 0); gl.enable(gl.DEPTH_TEST); gl.depthFunc(gl.LEQUAL); gl.clearDepth(1.0f); gl.clearColor(.5f, 1f, .5f, 1f); gl.lineWidth(2); var xOffs = 0; var yOffs = 0; var drag = 0; var xRot = 0f; var yRot = 0f; var transl = -6.0f; #region drawBall Action <f, f, f> drawBall = (x, y, z) => { mvMatrix.makeIdentity(); mvMatrix.translate(x, y, z); mvMatrix.multRight(rotMat); mvMatrix.translate(0, 0, transl); gl.uniformMatrix4fv(mvMatLoc, false, new Float32Array(mvMatrix.getAsArray())); gl.drawElements(gl.TRIANGLES, 6 * nPhi * nTheta, gl.UNSIGNED_SHORT, 72); }; #endregion #region drawScene Action drawScene = delegate { gl.viewport(0, 0, gl_viewportWidth, gl_viewportWidth); gl.useProgram(prog); gl.uniformMatrix4fv(gl.getUniformLocation(prog, "prMatrix"), false, new Float32Array(prMatrix.getAsArray())); rotMat.rotate(xRot / 5, 1, 0, 0); rotMat.rotate(yRot / 5, 0, 1, 0); yRot = 0; xRot = 0; gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); gl.uniform4f(colorLoc, 1, 1, 0, 1); drawBall(1, 1, 1); drawBall(-1, 1, 1); drawBall(1, -1, 1); drawBall(1, 1, -1); drawBall(-1, -1, 1); drawBall(-1, 1, -1); drawBall(1, -1, -1); drawBall(-1, -1, -1); mvMatrix.load(rotMat); mvMatrix.translate(0, 0, transl); gl.uniformMatrix4fv(mvMatLoc, false, new Float32Array(mvMatrix.getAsArray())); gl.enable(gl.BLEND); gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); gl.uniform4f(colorLoc, .0f, .0f, .9f, .7f); gl.depthMask(false); gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_SHORT, 0); gl.depthMask(true); gl.disable(gl.BLEND); gl.useProgram(line_prog); gl.uniformMatrix4fv(gl.getUniformLocation(line_prog, "prMatrix"), false, new Float32Array(prMatrix.getAsArray())); gl.uniformMatrix4fv(mvMatLineLoc, false, new Float32Array(mvMatrix.getAsArray())); gl.drawArrays(gl.LINES, 0, 24); gl.flush(); }; #endregion drawScene(); #region AtResize Action AtResize = delegate { gl_viewportWidth = Native.window.Width; gl_viewportHeight = Native.window.Height; prMatrix = new CanvasMatrix4(); //var aspect = (f)gl_viewportWidth / (f)gl_viewportHeight; var aspect = Native.window.aspect; Console.WriteLine( new { gl_viewportWidth, gl_viewportHeight, aspect } ); //Native.document.title = new { aspect }.ToString(); prMatrix.perspective(45f, (f)aspect, 1f, 100f); canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportHeight); canvas.width = gl_viewportWidth; canvas.height = gl_viewportHeight; drawScene(); }; AtResize(); Native.window.onresize += delegate { AtResize(); }; #endregion #region mouse canvas.onmousedown += ev => { ev.PreventDefault(); drag = 1; xOffs = ev.CursorX; yOffs = ev.CursorY; canvas.requestPointerLock(); }; canvas.onmouseup += ev => { ev.PreventDefault(); drag = 0; xOffs = ev.CursorX; yOffs = ev.CursorY; Native.Document.exitPointerLock(); }; canvas.onmousemove += ev => { if (drag == 0) { return; } if (Native.Document.pointerLockElement == canvas) { xRot += ev.movementY; yRot += ev.movementX; drawScene(); return; } ev.PreventDefault(); if (ev.shiftKey) { transl *= 1 + (ev.CursorY - yOffs) / 1000; yRot = -xOffs + ev.CursorX; } else { yRot = -xOffs + ev.CursorX; xRot = -yOffs + ev.CursorY; } xOffs = ev.CursorX; yOffs = ev.CursorY; drawScene(); }; #endregion #region onmousewheel canvas.onmousewheel += ev => { var del = 1.1f; if (ev.shiftKey) { del = 1.01f; } if (ev.WheelDirection > 0) { transl *= del; } else { transl *= (1 / del); } drawScene(); ev.PreventDefault(); }; #endregion #region IsDisposed var IsDisposed = false; this.Dispose = delegate { if (IsDisposed) { return; } IsDisposed = true; canvas.Orphanize(); }; #endregion #region requestFullscreen Native.Document.body.ondblclick += delegate { if (IsDisposed) { return; } // http://tutorialzine.com/2012/02/enhance-your-website-fullscreen-api/ canvas.requestFullscreen(); }; #endregion #region tick Native.window.onframe += delegate { if (IsDisposed) { return; } if (drag == 0) { xRot += 2; yRot += 3; } drawScene(); //animate(); }; #endregion //Native.Document.body.style.backgroundColor = Color.FromRGB(0x80, 0xFF, 0x80); }