public __DateTime() { this.Kind = DateTimeKind.Local; // fix for default(DateTime).ToString // X:\jsc.svn\examples\javascript\Test\TestDateTime\TestDateTime\Program.cs this.InternalValue = new IDate(); }
public __DateTime(long ticks, DateTimeKind kind) { //if ((ticks < 0L) || (ticks > 3155378975999999999L)) //{ // throw new Exception("ArgumentOutOfRange_DateTimeBadTicks"); //} var ms = (ticks - ticks_1970_1_1) / TicksPerMillisecond; this.InternalValue = new IDate(ms); this.Kind = kind; }
/// <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 size = 500; var gl = new WebGLRenderingContext(); var canvas = gl.canvas.AttachToDocument(); Native.document.body.style.overflow = IStyle.OverflowEnum.hidden; canvas.style.SetLocation(0, 0, size, size); canvas.width = size; canvas.height = size; var gl_viewportWidth = size; var gl_viewportHeight = size; #region toolbar var toolbar = new Toolbar(); if (page != null) { toolbar.Container.AttachToDocument(); toolbar.Container.style.Opacity = 0.7; toolbar.HideButton.onclick += delegate { // ScriptCoreLib.Extensions toolbar.HideTarget.ToggleVisible(); }; } #endregion #region IsDisposed var IsDisposed = false; this.Dispose = delegate { if (IsDisposed) return; IsDisposed = true; canvas.Orphanize(); }; #endregion #region AtResize Action AtResize = delegate { gl_viewportWidth = Native.window.Width; gl_viewportHeight = Native.window.Height; canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportHeight); canvas.width = gl_viewportWidth; canvas.height = gl_viewportHeight; }; Native.window.onresize += e => { AtResize(); }; AtResize(); #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 #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 #region programs var programs = new[] { gl.createProgram( new Shaders.PerFragmentLightingVertexShader(), new Shaders.PerFragmentLightingFragmentShader() ) }.Select( shaderProgram => { gl.linkProgram(shaderProgram); var vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); gl.enableVertexAttribArray((uint)vertexPositionAttribute); var vertexNormalAttribute = gl.getAttribLocation(shaderProgram, "aVertexNormal"); gl.enableVertexAttribArray((uint)vertexNormalAttribute); var textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord"); gl.enableVertexAttribArray((uint)textureCoordAttribute); var pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); var mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); var nMatrixUniform = gl.getUniformLocation(shaderProgram, "uNMatrix"); var colorMapSamplerUniform = gl.getUniformLocation(shaderProgram, "uColorMapSampler"); var specularMapSamplerUniform = gl.getUniformLocation(shaderProgram, "uSpecularMapSampler"); var useColorMapUniform = gl.getUniformLocation(shaderProgram, "uUseColorMap"); var useSpecularMapUniform = gl.getUniformLocation(shaderProgram, "uUseSpecularMap"); var useLightingUniform = gl.getUniformLocation(shaderProgram, "uUseLighting"); var ambientColorUniform = gl.getUniformLocation(shaderProgram, "uAmbientColor"); var pointLightingLocationUniform = gl.getUniformLocation(shaderProgram, "uPointLightingLocation"); var pointLightingSpecularColorUniform = gl.getUniformLocation(shaderProgram, "uPointLightingSpecularColor"); var pointLightingDiffuseColorUniform = gl.getUniformLocation(shaderProgram, "uPointLightingDiffuseColor"); return new { program = shaderProgram, vertexPositionAttribute, vertexNormalAttribute, textureCoordAttribute, pMatrixUniform, mvMatrixUniform, nMatrixUniform, colorMapSamplerUniform, specularMapSamplerUniform, useColorMapUniform, useSpecularMapUniform, useLightingUniform, ambientColorUniform, pointLightingLocationUniform, pointLightingSpecularColorUniform, pointLightingDiffuseColorUniform }; } ).ToArray(); #endregion var currentProgram = programs.First(); var mvMatrix = glMatrix.mat4.create(); var mvMatrixStack = new Stack<Float32Array>(); var pMatrix = glMatrix.mat4.create(); #region mvPushMatrix Action mvPushMatrix = delegate { var copy = glMatrix.mat4.create(); glMatrix.mat4.set(mvMatrix, copy); mvMatrixStack.Push(copy); }; #endregion #region mvPopMatrix Action mvPopMatrix = delegate { mvMatrix = mvMatrixStack.Pop(); }; #endregion #region degToRad Func<float, float> degToRad = (degrees) => { return degrees * (f)Math.PI / 180f; }; #endregion // await earth new HTML.Images.FromAssets.earth().InvokeOnComplete( earth => // await earth_specular new HTML.Images.FromAssets.earth_specular().InvokeOnComplete( earth_specular => { #region setMatrixUniforms Action setMatrixUniforms = delegate { #region [uniform] mat4 uPMatrix <- pMatrix gl.uniformMatrix4fv(currentProgram.pMatrixUniform, false, pMatrix); #endregion #region [uniform] mat4 uMVMatrix <- mvMatrix gl.uniformMatrix4fv(currentProgram.mvMatrixUniform, false, mvMatrix); #endregion var normalMatrix = glMatrix.mat3.create(); glMatrix.mat4.toInverseMat3(mvMatrix, normalMatrix); glMatrix.mat3.transpose(normalMatrix); #region [uniform] mat3 uNMatrix <- normalMatrix gl.uniformMatrix3fv(currentProgram.nMatrixUniform, false, normalMatrix); #endregion }; #endregion #region handleLoadedTexture Action<WebGLTexture, IHTMLImage> handleLoadedTexture = (texture, texture_image) => { gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1); gl.bindTexture(gl.TEXTURE_2D, texture); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture_image); gl.texParameteri((uint)gl.TEXTURE_2D, (uint)gl.TEXTURE_MAG_FILTER, (int)gl.LINEAR); gl.texParameteri((uint)gl.TEXTURE_2D, (uint)gl.TEXTURE_MIN_FILTER, (int)gl.LINEAR_MIPMAP_NEAREST); gl.generateMipmap(gl.TEXTURE_2D); gl.bindTexture(gl.TEXTURE_2D, null); }; #endregion var earthColorMapTexture = gl.createTexture(); handleLoadedTexture(earthColorMapTexture, earth); var earthSpecularMapTexture = gl.createTexture(); handleLoadedTexture(earthSpecularMapTexture, earth_specular); #region initBuffers var latitudeBands = 30; var longitudeBands = 30; var radius = 13; var vertexPositionData = new List<f>(); var normalData = new List<f>(); var textureCoordData = new List<f>(); for (var latNumber = 0; latNumber <= latitudeBands; latNumber++) { var theta = latNumber * Math.PI / latitudeBands; var sinTheta = (f)Math.Sin(theta); var cosTheta = (f)Math.Cos(theta); for (var longNumber = 0; longNumber <= longitudeBands; longNumber++) { var phi = longNumber * 2 * Math.PI / longitudeBands; var sinPhi = (f)Math.Sin(phi); var cosPhi = (f)Math.Cos(phi); var x = cosPhi * sinTheta; var y = cosTheta; var z = sinPhi * sinTheta; var u = 1 - (longNumber / longitudeBands); var v = 1 - (latNumber / latitudeBands); normalData.Add(x); normalData.Add(y); normalData.Add(z); textureCoordData.Add(u); textureCoordData.Add(v); vertexPositionData.Add(radius * x); vertexPositionData.Add(radius * y); vertexPositionData.Add(radius * z); } } var indexData = new List<ushort>(); for (var latNumber = 0; latNumber < latitudeBands; latNumber++) { for (var longNumber = 0; longNumber < longitudeBands; longNumber++) { var first = (latNumber * (longitudeBands + 1)) + longNumber; var second = first + longitudeBands + 1; indexData.Add((ushort)first); indexData.Add((ushort)second); indexData.Add((ushort)(first + 1)); indexData.Add((ushort)second); indexData.Add((ushort)(second + 1)); indexData.Add((ushort)(first + 1)); } } var sphereVertexNormalBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, sphereVertexNormalBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(normalData.ToArray()), gl.STATIC_DRAW); var sphereVertexNormalBuffer_itemSize = 3; var sphereVertexNormalBuffer_numItems = normalData.Count / 3; var sphereVertexTextureCoordBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, sphereVertexTextureCoordBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoordData.ToArray()), gl.STATIC_DRAW); var sphereVertexTextureCoordBuffer_itemSize = 2; var sphereVertexTextureCoordBuffer_numItems = textureCoordData.Count / 2; var sphereVertexPositionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, sphereVertexPositionBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexPositionData.ToArray()), gl.STATIC_DRAW); var sphereVertexPositionBuffer_itemSize = 3; var sphereVertexPositionBuffer_numItems = vertexPositionData.Count / 3; var sphereVertexIndexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, sphereVertexIndexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexData.ToArray()), gl.STREAM_DRAW); var sphereVertexIndexBuffer_itemSize = 1; var sphereVertexIndexBuffer_numItems = indexData.Count; #endregion gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); gl.enable(gl.DEPTH_TEST); var earthAngle = 180f; var lastTime = 0L; #region animate Action animate = () => { var timeNow = new IDate().getTime(); if (lastTime != 0) { var elapsed = timeNow - lastTime; earthAngle += 0.05f * elapsed; } lastTime = timeNow; }; #endregion //Func<string, f> parseFloat = Convert.ToSingle; //Func<string, f> parseFloat = x => float.Parse(x); #region drawScene Action drawScene = () => { var shaderProgram = currentProgram; gl.useProgram(shaderProgram.program); gl.viewport(0, 0, gl_viewportWidth, gl_viewportHeight); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); glMatrix.mat4.perspective(45, gl_viewportWidth / gl_viewportHeight, 0.1f, 100.0f, pMatrix); #region [uniform] uUseColorMap <- color_map var useColorMap = toolbar.color_map.@checked; gl.uniform1i(shaderProgram.useColorMapUniform, Convert.ToInt32(useColorMap)); #endregion #region [uniform] uUseSpecularMap <- specular_map var useSpecularMap = toolbar.specular_map.@checked; gl.uniform1i(shaderProgram.useSpecularMapUniform, Convert.ToInt32(useSpecularMap)); #endregion #region [uniform] uUseLighting <- lighting var lighting = toolbar.lighting.@checked; gl.uniform1i(shaderProgram.useLightingUniform, Convert.ToInt32(lighting)); #endregion if (lighting) { #region [uniform] uAmbientColor <- ambientR, ambientG, ambientB gl.uniform3f( shaderProgram.ambientColorUniform, float.Parse(toolbar.ambientR.value), float.Parse(toolbar.ambientG.value), float.Parse(toolbar.ambientB.value) ); #endregion #region [uniform] uPointLightingLocation <- lightPositionX, lightPositionY, lightPositionZ gl.uniform3f( shaderProgram.pointLightingLocationUniform, float.Parse(toolbar.lightPositionX.value), float.Parse(toolbar.lightPositionY.value), float.Parse(toolbar.lightPositionZ.value) ); #endregion #region [uniform] uPointLightingSpecularColor <- specularR, specularG, specularB gl.uniform3f( shaderProgram.pointLightingSpecularColorUniform, float.Parse(toolbar.specularR.value), float.Parse(toolbar.specularG.value), float.Parse(toolbar.specularB.value) ); #endregion #region [uniform] uPointLightingDiffuseColor <- diffuseR, diffuseG, diffuseB gl.uniform3f( shaderProgram.pointLightingDiffuseColorUniform, float.Parse(toolbar.diffuseR.value), float.Parse(toolbar.diffuseG.value), float.Parse(toolbar.diffuseB.value) ); #endregion } glMatrix.mat4.identity(mvMatrix); glMatrix.mat4.translate(mvMatrix, new f[] { 0, 0, -40 }); glMatrix.mat4.rotate(mvMatrix, degToRad(23.4f), new f[] { 1, 0, -1 }); glMatrix.mat4.rotate(mvMatrix, degToRad(earthAngle), new f[] { 0, 1, 0 }); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, earthColorMapTexture); gl.uniform1i(shaderProgram.colorMapSamplerUniform, 0); gl.activeTexture(gl.TEXTURE1); gl.bindTexture(gl.TEXTURE_2D, earthSpecularMapTexture); gl.uniform1i(shaderProgram.specularMapSamplerUniform, 1); gl.bindBuffer(gl.ARRAY_BUFFER, sphereVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram.vertexPositionAttribute, sphereVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, sphereVertexTextureCoordBuffer); gl.vertexAttribPointer((uint)shaderProgram.textureCoordAttribute, sphereVertexTextureCoordBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, sphereVertexNormalBuffer); gl.vertexAttribPointer((uint)shaderProgram.vertexNormalAttribute, sphereVertexNormalBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, sphereVertexIndexBuffer); setMatrixUniforms(); gl.drawElements(gl.TRIANGLES, sphereVertexIndexBuffer_numItems, gl.UNSIGNED_SHORT, 0); }; #endregion Native.window.onframe += delegate { if (IsDisposed) return; animate(); drawScene(); }; } ) ); }
/// <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) { // used by // X:\jsc.svn\examples\javascript\WebGL\WebGLGoldDropletTransactions\WebGLGoldDropletTransactions\Application.cs if (DisableBackground) { // nop } else { //page.body.style.backgroundColor = "#4584b4"; container.style.backgroundColor = "#4584b4"; } // Bg gradient //var canvas = new IHTMLCanvas(); //canvas.width = 32; //canvas.height = Native.Window.Height; //var context = (CanvasRenderingContext2D)canvas.getContext("2d"); //var gradient = context.createLinearGradient(0, 0, 0, canvas.height); //gradient.addColorStop(0f, "#1e4877"); //gradient.addColorStop(0.5f, "#4584b4"); //context.fillStyle = gradient; //context.fillRect(0, 0, canvas.width, canvas.height); // Clouds //var , , renderer, sky, mesh, , material, //, h, color, colors = [], sprite, size, x, y, z; var mouseX = 0f; var start_time = new IDate().getTime(); Console.WriteLine(new { Native.window.Width, Native.window.Height }); var windowHalfX = Native.window.Width / 2; var windowHalfY = Native.window.Height / 2; Console.WriteLine(new { DefaultMouseY }); var mouseY = (float)((Native.window.Height * DefaultMouseY - windowHalfY) * 0.15); //Native.document.body.style.overflow = IStyle.OverflowEnum.hidden; if (page == null) { container.AttachToDocument(); } else { container.AttachTo(page.body); } container.style.SetLocation(0, 0, Native.window.Width, Native.window.Height); //container.style.background = "url(" + canvas.toDataURL("image/png") + ")"; #region Dispose var IsDisposed = false; Dispose = delegate { if (IsDisposed) return; IsDisposed = true; container.Orphanize(); }; #endregion var camera = new THREE.PerspectiveCamera(30, Native.window.aspect, 1, 3000); camera.position.z = 6000; var scene = new THREE.Scene(); var geometry = new THREE.Geometry(); //var texture = THREE.ImageUtils.loadTexture(new HTML.Images.FromAssets.cloud10().src); var texture = THREE.ImageUtils.loadTexture(CloudTexture); texture.magFilter = THREE.LinearMipMapLinearFilter; texture.minFilter = THREE.LinearMipMapLinearFilter; // FogColor //var fog = new THREE.Fog(0x4584b4, -100, 3000); var fog = new THREE.Fog(FogColor, -100, 3000); // what about sprites? var material = new THREE.ShaderMaterial( new { uniforms = new { map = new { type = "t", value = texture }, fogColor = new { type = "c", value = fog.color }, fogNear = new { type = "f", value = fog.near }, fogFar = new { type = "f", value = fog.far }, }, vertexShader = new GeometryVertexShader().ToString(), fragmentShader = new GeometryFragmentShader().ToString(), depthWrite = false, depthTest = false, transparent = true } ); var r = new Random(); Func<float> Math_random = () => (float)r.NextDouble(); var plane = new THREE.Mesh(new THREE.PlaneGeometry(64, 64)); for (var i = 0; i < 8000; i++) { plane.position.x = Math_random() * 1000 - 500; plane.position.y = -Math_random() * Math_random() * 200 - 15; plane.position.z = i; plane.rotation.z = (f)(Math_random() * Math.PI); plane.scale.x = Math_random() * Math_random() * 1.5f + 0.5f; plane.scale.y = plane.scale.x; THREE.GeometryUtils.merge(geometry, plane); } var mesh = new THREE.Mesh(geometry, material); scene.add(mesh); mesh = new THREE.Mesh(geometry, material); mesh.position.z = -8000; scene.add(mesh); var renderer = new THREE.WebGLRenderer(new { antialias = false }); renderer.setSize(Native.window.Width, Native.window.Height); container.appendChild(renderer.domElement); container.style.SetLocation(0, 0, Native.window.Width, Native.window.Height); #region onresize Native.window.onresize += delegate { container.style.SetSize(Native.window.Width, Native.window.Height); camera.aspect = Native.window.aspect; camera.updateProjectionMatrix(); renderer.setSize(Native.window.Width, Native.window.Height); }; #endregion #region animate Native.window.onframe += delegate { if (IsDisposed) return; var position = ((new IDate().getTime() - start_time) * 0.03) % 8000; camera.position.x += (float)((mouseX - camera.position.x) * 0.01); camera.position.y += (float)((-mouseY - camera.position.y) * 0.01); camera.position.z = (f)(-position + 8000); renderer.render(scene, camera); }; #endregion Native.document.onmousemove += e => { mouseX = (float)((e.CursorX - windowHalfX) * 0.25); mouseY = (float)((e.CursorY - windowHalfY) * 0.15); }; //var ze = new ZeProperties(); //ze.Show(); //ze.Add(() => renderer); ////ze.Add(() => controls); //ze.Add(() => scene); }
// samsung gearvr browser doesnt have webgl enabled yet // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20151201/samsungbrowser // https://zproxy.wordpress.com/2015/07/04/gearvr-ovrmycubeworldndk/ /// <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) { // X:\jsc.svn\examples\java\android\vr\OVRMyCubeWorldNDK\OVRMyCubeWorldNDK\VrCubeWorld.Renderer.cs // works for IE11 //DiagnosticsConsole.ApplicationContent.BindKeyboardToDiagnosticsConsole(); //if (Native.window.parent != Native.window.self) //{ // // why stop there. negotiate our own title bar! // Native.document.body.style.backgroundColor = JSColor.Transparent; //} //else //{ Native.window.document.body.style.backgroundColor = JSColor.Black; Native.window.document.body.style.color = JSColor.Yellow; //} //page.PageContainer.style.color = Color.Blue; var size = 600; var gl = new WebGLRenderingContext(); var canvas = gl.canvas.AttachToDocument(); Native.document.body.style.overflow = IStyle.OverflowEnum.hidden; canvas.style.SetLocation(0, 0, size, size); canvas.width = size; canvas.height = size; var gl_viewportWidth = size; var gl_viewportHeight = size; #region AtResize Action AtResize = delegate { gl_viewportWidth = Native.window.Width; gl_viewportHeight = Native.window.Height; canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportHeight); canvas.width = gl_viewportWidth; canvas.height = gl_viewportHeight; }; Native.window.onresize += e => { AtResize(); }; AtResize(); #endregion var shaderProgram = gl.createProgram( new GeometryVertexShader(), new GeometryFragmentShader() ); gl.linkProgram(shaderProgram); gl.useProgram(shaderProgram); var shaderProgram_vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); gl.enableVertexAttribArray((uint)shaderProgram_vertexPositionAttribute); // new in lesson 02 var shaderProgram_vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor"); gl.enableVertexAttribArray((uint)shaderProgram_vertexColorAttribute); var shaderProgram_pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); var shaderProgram_mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); // X:\jsc.svn\examples\java\android\vr\OVRMyCubeWorldNDK\OVRMyCubeWorldNDK\References\VrApi.ovrMatrix4f.cs // exports.mat4 = require("./gl-matrix/mat4.js"); // https://github.com/toji/gl-matrix/blob/master/src/gl-matrix.js // https://github.com/toji/gl-matrix/blob/master/src/gl-matrix/mat4.js // new glMatrix.ARRAY_TYPE(16); // https://github.com/toji/gl-matrix/blob/master/src/gl-matrix/common.js // Float32Array : Array var __mat4 = new { // X:\jsc.svn\examples\javascript\Test\TestFloatArray\TestFloatArray\Application.cs // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2015/20150706/20150708 create = new Func<float[]>( () => new float[] { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, } ) }; // should jsc default to Float32Array ? //var __mvMatrix = new float[] //{ // 1, 0, 0, 0, // 0, 1, 0, 0, // 0, 0, 1, 0, // 0, 0, 0, 1, //}; //var mvMatrix = glMatrix.mat4.create(); var mvMatrix = __mat4.create(); // for js we erased the generic type.. var mvMatrixStack = new Stack<float[]>(); // X:\jsc.svn\examples\javascript\WebGL\WebGLSpadeWarrior\WebGLSpadeWarrior\Shaders\GeometryVertexShader.cs var pMatrix = __mat4.create(); //var pMatrix = new ScriptCoreLib.GLSL.mat4(1); //var pMatrix = glMatrix.mat4.create(); #region mvMatrixScope Action mvPushMatrix = delegate { var copy = __mat4.create(); glMatrix.mat4.set(mvMatrix, copy); mvMatrixStack.Push(copy); }; Action mvPopMatrix = delegate { mvMatrix = mvMatrixStack.Pop(); }; Action<Action> mvMatrixScope = h => { mvPushMatrix(); h(); mvPopMatrix(); }; #endregion #region setMatrixUniforms Action setMatrixUniforms = delegate { gl.uniformMatrix4fv(shaderProgram_pMatrixUniform, false, pMatrix); gl.uniformMatrix4fv(shaderProgram_mvMatrixUniform, false, mvMatrix); }; #endregion #region init buffers #region cube var cubeVertexPositionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); var cubesize = 1.0f * 0.02f; var vertices = new[]{ // Front face -cubesize, -cubesize, cubesize, cubesize, -cubesize, cubesize, cubesize, cubesize, cubesize, -cubesize, cubesize, cubesize, // Back face -cubesize, -cubesize, -cubesize, -cubesize, cubesize, -cubesize, cubesize, cubesize, -cubesize, cubesize, -cubesize, -cubesize, // Top face -cubesize, cubesize, -cubesize, -cubesize, cubesize, cubesize, cubesize, cubesize, cubesize, cubesize, cubesize, -cubesize, // Bottom face -cubesize, -cubesize, -cubesize, cubesize, -cubesize, -cubesize, cubesize, -cubesize, cubesize, -cubesize, -cubesize, cubesize, // Right face cubesize, -cubesize, -cubesize, cubesize, cubesize, -cubesize, cubesize, cubesize, cubesize, cubesize, -cubesize, cubesize, // Left face -cubesize, -cubesize, -cubesize, -cubesize, -cubesize, cubesize, -cubesize, cubesize, cubesize, -cubesize, cubesize, -cubesize }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); var cubeVertexPositionBuffer_itemSize = 3; var cubeVertexPositionBuffer_numItems = 36; // 216, 191, 18 #region colors1 var colors_orange = new[]{ 1.0f, 0.6f, 0.0f, 1.0f, // Front face 1.0f, 0.6f, 0.0f, 1.0f, // Front face 1.0f, 0.6f, 0.0f, 1.0f, // Front face 1.0f, 0.6f, 0.0f, 1.0f, // Front face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Left face 1.0f, 0.8f, 0.0f, 1.0f, // Left face 1.0f, 0.8f, 0.0f, 1.0f, // Left face 1.0f, 0.8f, 0.0f, 1.0f // Left face }; var cubeVertexColorBuffer_orange = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer_orange); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors_orange), gl.STATIC_DRAW); #endregion #region colors2 var colors2 = new[]{ 0.0f, 0.6f, 1.0f, 1.0f, // Front face 0.0f, 0.6f, 1.0f, 1.0f, // Front face 0.0f, 0.6f, 1.0f, 1.0f, // Front face 0.0f, 0.6f, 1.0f, 1.0f, // Front face 0.0f, 0.4f, 0.8f, 1.0f, // Back face 0.0f, 0.4f, 0.8f, 1.0f, // Back face 0.0f, 0.4f, 0.8f, 1.0f, // Back face 0.0f, 0.4f, 0.8f, 1.0f, // Back face 0.0f, 0.5f, 0.9f, 1.0f, // Top face 0.0f, 0.5f, 0.9f, 1.0f, // Top face 0.0f, 0.5f, 0.9f, 1.0f, // Top face 0.0f, 0.5f, 0.9f, 1.0f, // Top face 0.0f, 0.5f, 1.0f, 1.0f, // Bottom face 0.0f, 0.5f, 1.0f, 1.0f, // Bottom face 0.0f, 0.5f, 1.0f, 1.0f, // Bottom face 0.0f, 0.5f, 1.0f, 1.0f, // Bottom face 0.0f, 0.8f, 1.0f, 1.0f, // Right face 0.0f, 0.8f, 1.0f, 1.0f, // Right face 0.0f, 0.8f, 1.0f, 1.0f, // Right face 0.0f, 0.8f, 1.0f, 1.0f, // Right face 0.0f, 0.8f, 1.0f, 1.0f, // Left face 0.0f, 0.8f, 1.0f, 1.0f, // Left face 0.0f, 0.8f, 1.0f, 1.0f, // Left face 0.0f, 0.8f, 1.0f, 1.0f // Left face }; var cubeVertexColorBuffer2 = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer2); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors2), gl.STATIC_DRAW); #endregion #region colors3 var colors_green = new[]{ 0.0f, 1.0f, 0.0f, 1.0f, // Front face 0.0f, 1.0f, 0.0f, 1.0f, // Front face 0.0f, 1.0f, 0.0f, 1.0f, // Front face 0.0f, 1.0f, 0.0f, 1.0f, // Front face 0.0f, 0.4f, 0.0f, 1.0f, // Back face 0.0f, 0.4f, 0.0f, 1.0f, // Back face 0.0f, 0.4f, 0.0f, 1.0f, // Back face 0.0f, 0.4f, 0.0f, 1.0f, // Back face 0.0f, 0.5f, 0.0f, 1.0f, // Top face 0.0f, 0.5f, 0.0f, 1.0f, // Top face 0.0f, 0.5f, 0.0f, 1.0f, // Top face 0.0f, 0.5f, 0.0f, 1.0f, // Top face 0.0f, 0.7f, 0.0f, 1.0f, // Bottom face 0.0f, 0.7f, 0.0f, 1.0f, // Bottom face 0.0f, 0.7f, 0.0f, 1.0f, // Bottom face 0.0f, 0.7f, 0.0f, 1.0f, // Bottom face 0.0f, 0.8f, 0.0f, 1.0f, // Right face 0.0f, 0.8f, 0.0f, 1.0f, // Right face 0.0f, 0.8f, 0.0f, 1.0f, // Right face 0.0f, 0.8f, 0.0f, 1.0f, // Right face 0.0f, 0.9f, 0.0f, 1.0f, // Left face 0.0f, 0.9f, 0.0f, 1.0f, // Left face 0.0f, 0.9f, 0.0f, 1.0f, // Left face 0.0f, 0.9f, 0.0f, 1.0f // Left face }; var cubeVertexColorBuffer_green = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer_green); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors_green), gl.STATIC_DRAW); #endregion #region colors_black var colors_black = new[]{ 0.0f, 0.0f, 0.0f, 1.0f, // Front face 0.0f, 0.0f, 0.0f, 1.0f, // Front face 0.0f, 0.0f, 0.0f, 1.0f, // Front face 0.0f, 0.0f, 0.0f, 1.0f, // Front face 0.0f, 0.0f, 0.0f, 1.0f, // Back face 0.0f, 0.0f, 0.0f, 1.0f, // Back face 0.0f, 0.0f, 0.0f, 1.0f, // Back face 0.0f, 0.0f, 0.0f, 1.0f, // Back face 0.0f, 0.0f, 0.0f, 1.0f, // Top face 0.0f, 0.0f, 0.0f, 1.0f, // Top face 0.0f, 0.0f, 0.0f, 1.0f, // Top face 0.0f, 0.0f, 0.0f, 1.0f, // Top face 0.0f, 0.0f, 0.0f, 1.0f, // Bottom face 0.0f, 0.0f, 0.0f, 1.0f, // Bottom face 0.0f, 0.0f, 0.0f, 1.0f, // Bottom face 0.0f, 0.0f, 0.0f, 1.0f, // Bottom face 0.0f, 0.0f, 0.0f, 1.0f, // Right face 0.0f, 0.0f, 0.0f, 1.0f, // Right face 0.0f, 0.0f, 0.0f, 1.0f, // Right face 0.0f, 0.0f, 0.0f, 1.0f, // Right face 0.0f, 0.0f, 0.0f, 1.0f, // Left face 0.0f, 0.0f, 0.0f, 1.0f, // Left face 0.0f, 0.0f, 0.0f, 1.0f, // Left face 0.0f, 0.0f, 0.0f, 1.0f // Left face }; var cubeVertexColorBuffer_black = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer_black); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors_black), gl.STATIC_DRAW); #endregion var cubeVertexColorBuffer_itemSize = 4; var cubeVertexColorBuffer_numItems = 24; var cubeVertexIndexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); var cubeVertexIndices = new UInt16[]{ 0, 1, 2, 0, 2, 3, // Front face 4, 5, 6, 4, 6, 7, // Back face 8, 9, 10, 8, 10, 11, // Top face 12, 13, 14, 12, 14, 15, // Bottom face 16, 17, 18, 16, 18, 19, // Right face 20, 21, 22, 20, 22, 23 // Left face }; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW); var cubeVertexIndexBuffer_itemSize = 1; var cubeVertexIndexBuffer_numItems = 36; #endregion #endregion //gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f); gl.enable(gl.DEPTH_TEST); var IsWalking = false; var WalkMultiplier = 0.0f; var ego_x = 0f; var ego_y = 0f; var ego_z = 0f; var ego_za = 0f; var rCube = 0f; var raCube = 0f; var lastTime = 0L; Action animate = delegate { var timeNow = new IDate().getTime(); if (lastTime != 0) { var elapsed = timeNow - lastTime; var u = ego_z + ego_za * (elapsed) / 1000.0f; if (u < 0) ego_z = (float)Math.Min(ego_z, 0); else ego_z = u; ego_za -= 3.2f * (elapsed) / 1000.0f; raCube += (75 * elapsed) / 1000.0f; } lastTime = timeNow; }; Func<float, float> degToRad = (degrees) => { return degrees * (f)Math.PI / 180f; }; var c = 0; #region drawScene Action drawScene = delegate { if (ego_x < 0) ego_x = 0; if (ego_y > 0) ego_y = 0; gl.viewport(0, 0, gl_viewportWidth, gl_viewportHeight); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); glMatrix.mat4.perspective(45f, (float)gl_viewportWidth / (float)gl_viewportHeight, 0.1f, 100.0f, pMatrix); glMatrix.mat4.identity(mvMatrix); #region vertex gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, cubeVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); #endregion //__glMatrix.mat4.rotate(mvMatrix, degToRad(-33), new float[] { 0f, 1f, 0f }); //__glMatrix.mat4.rotate(mvMatrix, rCube, new float[] { 1f, 0f, 0f }); #region OriginalCubeAt Action<float, float, float> OriginalCubeAt = (x, y, z) => { mvMatrixScope( delegate { glMatrix.mat4.translate(mvMatrix, new float[] { x, y, z }); glMatrix.mat4.rotate(mvMatrix, degToRad(raCube), new float[] { 1f, 1f, 1f }); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); setMatrixUniforms(); gl.drawElements(gl.TRIANGLES, cubeVertexPositionBuffer_numItems, gl.UNSIGNED_SHORT, 0); } ); }; #endregion mvMatrixScope( delegate { glMatrix.mat4.translate(mvMatrix, new float[] { - 1.5f, 0, - 7f}); glMatrix.mat4.rotate(mvMatrix, degToRad(-80), new float[] { 1f, 0f, 0f }); #region grid #region color gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer_green); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); #endregion var GridZoom = 0.3f; Action<float> WriteYLine = x => { for (int i = -12; i < -1; i++) { OriginalCubeAt(x * GridZoom, (i) * GridZoom, 0); } }; for (int i = 1; i < 12; i++) WriteYLine(i); #region color gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer_orange); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); #endregion for (int i = 1; i < 12; i++) OriginalCubeAt(i * GridZoom, 0, 0); for (int i = -12; i < 0; i++) OriginalCubeAt(0, (i) * GridZoom, 0); #endregion #region color gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer2); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); #endregion { var _y = (float)Math.Cos(raCube * 0.05f) * 0.1f; var _x = (float)Math.Sin(raCube * 0.05f) * 0.1f; OriginalCubeAt(_x, _y, 0); } { var _y = (float)Math.Sin(rCube) * 0.2f; var _x = (float)Math.Cos(rCube) * 0.2f; OriginalCubeAt(_x, _y, 0); } mvMatrixScope( delegate { // where are we glMatrix.mat4.translate(mvMatrix, new float[] { ego_x, ego_y, ego_z }); // rotate all of it //__glMatrix.mat4.rotate(mvMatrix, degToRad(-45), new float[] { 1f, 0f, 0f }); // which way are we looking at? glMatrix.mat4.rotate(mvMatrix, rCube, new float[] { 0f, 0f, 1f }); #region cube Action<float, float, float> cube = (x, y, z) => { mvPushMatrix(); glMatrix.mat4.translate(mvMatrix, new float[] { 2 * cubesize * x, 2 * cubesize * y, 2 * cubesize * z}); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); setMatrixUniforms(); gl.drawElements(gl.TRIANGLES, cubeVertexPositionBuffer_numItems, gl.UNSIGNED_SHORT, 0); mvPopMatrix(); }; #endregion cube #region draw Action<int, int, int> rect = (ix, iy, z) => { for (int y = 0; y < ix; y++) { for (int x = 0; x < iy; x++) { cube(x, y, z); } } }; #endregion draw #region leg Action<int, float, float> leg = (y, hiprotation, kneerotation) => { mvPushMatrix(); #region hiprotation glMatrix.mat4.translate(mvMatrix, new float[] { 2 * cubesize * 2, 2 * cubesize * 0, 2 * cubesize * 11}); glMatrix.mat4.rotate(mvMatrix, degToRad(hiprotation), new float[] { 0f, 1f, 0f }); glMatrix.mat4.translate(mvMatrix, new float[] { 2 * cubesize * -2, 2 * cubesize * 0, 2 * cubesize * -11}); #endregion glMatrix.mat4.translate(mvMatrix, new float[] { 2 * cubesize * 1, 2 * cubesize * y, 2 * cubesize * 0}); mvPushMatrix(); #region kneerotation glMatrix.mat4.translate(mvMatrix, new float[] { 2 * cubesize * 1, 2 * cubesize * 0, 2 * cubesize * 6f}); glMatrix.mat4.rotate(mvMatrix, degToRad(kneerotation), new float[] { 0f, 1f, 0f }); glMatrix.mat4.translate(mvMatrix, new float[] { 2 * cubesize * -1, 2 * cubesize * 0, 2 * cubesize * -6f}); #endregion #region color gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer_orange); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); #endregion #region lower leg rect(3, 5, 0); rect(3, 5, 1); rect(3, 5, 2); rect(3, 3, 3); #endregion #region color gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer2); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); #endregion rect(3, 3, 4); rect(3, 3, 5); rect(3, 3, 6); mvPopMatrix(); #region upper leg mvPushMatrix(); glMatrix.mat4.translate(mvMatrix, new float[] { 2 * cubesize * 1, 2 * cubesize * 0, 2 * cubesize * 0}); rect(3, 3, 7); rect(3, 3, 8); rect(3, 3, 9); mvPopMatrix(); #endregion #region hips rect(3, 4, 10); //rect(3, 4, 11); #endregion mvPopMatrix(); }; #endregion var seed = (raCube * WalkMultiplier * 16); #region animated_leg Action<int, int> animated_leg = (seed_offset, x) => { var seed_180 = (float)((seed + seed_offset) % 180f); var left_hip = 30f; var left_knee = 0f; if (ego_z < 0) { // crouch left_hip = -66; left_knee = left_hip * -2; } else if (ego_z > 0) { // crouch left_hip = 10; left_knee = 10; } else if (!IsWalking) { left_hip = 0; left_knee = 0; } else { left_hip = seed_180; if (left_hip > 90) { left_hip = 180 - left_hip; // -60 should be 0 - front // 0 should be 60 // 30 should be 0 - back var v = (90 - left_hip) - 70; if (v < 0) left_knee = 70 + v; else if (v == 0) left_knee = 70; else if (v > 0) left_knee = (20 - v) * (70 / 20); //page.Data1.innerText = "" + new { left_hip, v, left_knee }; } else { } left_hip -= 45; } leg(x, left_hip, left_knee); }; #endregion animated_leg(0, -2); animated_leg(90, 3); #region body mvMatrixScope( delegate { glMatrix.mat4.translate(mvMatrix, new float[] { 2 * cubesize * 1, 2 * cubesize * -2, 2 * cubesize * 11}); rect(8, 4, 0); rect(8, 4, 1); rect(8, 4, 2); rect(8, 4, 3); rect(8, 4, 4); rect(8, 4, 5); rect(8, 4, 6); rect(8, 4, 7); rect(8, 4, 8); mvMatrixScope( delegate { glMatrix.mat4.translate(mvMatrix, new float[] { 2 * cubesize * 0, 2 * cubesize * -2, 2 * cubesize * 7}); rect(2, 10, 0); rect(2, 10, 1); } ); mvMatrixScope( delegate { #region color gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer_orange); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); #endregion glMatrix.mat4.translate(mvMatrix, new float[] { 2 * cubesize * 10, 2 * cubesize * -2, 2 * cubesize * 7}); rect(2, 2, 0); rect(2, 2, 1); #region color gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer2); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); #endregion } ); mvMatrixScope( delegate { #region color gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer_orange); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); #endregion glMatrix.mat4.translate(mvMatrix, new float[] { 2 * cubesize * 10, 2 * cubesize * 8, 2 * cubesize * 7}); rect(2, 2, 0); rect(2, 2, 1); #region color gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer2); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); #endregion } ); mvMatrixScope( delegate { glMatrix.mat4.translate(mvMatrix, new float[] { 2 * cubesize * 0, 2 * cubesize * 8, 2 * cubesize * 7}); rect(2, 10, 0); rect(2, 10, 1); } ); } ); #endregion #region head mvMatrixScope( delegate { glMatrix.mat4.translate(mvMatrix, new float[] { 2 * cubesize * 0, 2 * cubesize * -1, 2 * cubesize * 20}); #region color gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer_black); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); #endregion cube(5, 4, 2); cube(5, 1, 2); cube(3, 0, 0); cube(3, 0, 1); cube(3, 0, 2); cube(3, 5, 0); cube(3, 5, 1); cube(3, 5, 2); #region color gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer_orange); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); #endregion rect(6, 3, 0); rect(6, 3, 1); cube(4, 0, 2); cube(5, 0, 2); cube(5, 2, 2); cube(5, 3, 2); cube(5, 5, 2); cube(4, 5, 2); cube(4, 0, 1); cube(5, 0, 1); cube(5, 1, 1); cube(5, 2, 1); cube(5, 3, 1); cube(5, 4, 1); cube(5, 5, 1); cube(4, 5, 1); cube(4, 0, 0); cube(5, 0, 0); cube(5, 1, 0); cube(5, 2, 0); cube(5, 3, 0); cube(5, 4, 0); cube(5, 5, 0); cube(4, 5, 0); //rect(6, 2, 2); #region color gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer2); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); #endregion // 3 or 3?? :) rect(6, 3, 2); rect(6, 6, 3); rect(6, 6, 4); rect(6, 6, 5); } ); #endregion } ); } ); }; drawScene(); #endregion Native.window.onframe += delegate { c++; Native.document.title = "" + c + " " + (rCube) + " " + ego_z + " " + ego_za; drawScene(); animate(); }; #region onkeyup Native.document.onkeyup += (e) => { //Native.Document.title = "" + new { e.KeyCode }; if (e.KeyCode == 17) { ego_z = 0; } if (e.KeyCode == 32) { ego_z = 0; ego_za = 2; } if (e.KeyCode == 38) { IsWalking = false; } if (e.KeyCode == 40) { IsWalking = false; } }; #endregion #region onkeydown Native.document.onkeydown += (e) => { // see also: http://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes e.preventDefault(); #region turnspeed var turnspeed = 0.05f; if (e.KeyCode == 37) { // left rCube += turnspeed; } if (e.KeyCode == 65) { // left rCube += turnspeed; } if (e.KeyCode == 39) { rCube -= turnspeed; // right } if (e.KeyCode == 68) { rCube -= turnspeed; // right } #endregion if (e.KeyCode == 17) { ego_z = -cubesize * 6; } if (e.KeyCode == 32) { ego_z = -cubesize * 6; } if (ego_z > 0) { // not on ground. cant walk :) } else { if (e.KeyCode == 38) { IsWalking = true; // mat aint working .. if (!e.shiftKey) { WalkMultiplier = 0.04f; } else { WalkMultiplier = 0.02f; } ego_y += (float)Math.Sin(rCube) * WalkMultiplier; ego_x += (float)Math.Cos(rCube) * WalkMultiplier; } if (e.KeyCode == 40) { IsWalking = true; WalkMultiplier = 0.02f; ego_y -= (float)Math.Sin(rCube) * WalkMultiplier; ego_x -= (float)Math.Cos(rCube) * WalkMultiplier; } } }; #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 //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.style.color = "yellow"; // dragme.AllowToDragAsApplicationPackage(); // } //); }
void InitializeContent(IDefaultPage page) { page.PageContainer.style.color = Color.Blue; var size = 600; #region canvas var canvas = new IHTMLCanvas().AttachToDocument(); Native.Document.body.style.overflow = IStyle.OverflowEnum.hidden; canvas.style.SetLocation(0, 0, size, size); canvas.width = size; canvas.height = size; #endregion #region gl - Initialise WebGL var gl = default(WebGLRenderingContext); try { gl = (WebGLRenderingContext)canvas.getContext("experimental-webgl"); } catch { } if (gl == null) { Native.Window.alert("WebGL not supported"); throw new InvalidOperationException("cannot create webgl context"); } #endregion var gl_viewportWidth = size; var gl_viewportHeight = size; var shaderProgram = 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)); return null; } return shader; }; #endregion var vs = createShader(new GeometryVertexShader()); var fs = createShader(new GeometryFragmentShader()); if (vs == null || fs == null) throw new InvalidOperationException("shader failed"); gl.attachShader(shaderProgram, vs); gl.attachShader(shaderProgram, fs); gl.linkProgram(shaderProgram); gl.useProgram(shaderProgram); var shaderProgram_vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); gl.enableVertexAttribArray((ulong)shaderProgram_vertexPositionAttribute); // new in lesson 02 var shaderProgram_vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor"); gl.enableVertexAttribArray((ulong)shaderProgram_vertexColorAttribute); var shaderProgram_pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); var shaderProgram_mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); var mvMatrix = __glMatrix.mat4.create(); var mvMatrixStack = new Stack<Float32Array>(); var pMatrix = __glMatrix.mat4.create(); #region mvMatrixScope Action mvPushMatrix = delegate { var copy = __glMatrix.mat4.create(); __glMatrix.mat4.set(mvMatrix, copy); mvMatrixStack.Push(copy); }; Action mvPopMatrix = delegate { mvMatrix = mvMatrixStack.Pop(); }; Action<Action> mvMatrixScope = h => { mvPushMatrix(); h(); mvPopMatrix(); }; #endregion #region setMatrixUniforms Action setMatrixUniforms = delegate { gl.uniformMatrix4fv(shaderProgram_pMatrixUniform, false, pMatrix); gl.uniformMatrix4fv(shaderProgram_mvMatrixUniform, false, mvMatrix); }; #endregion #region init buffers #region cube var cubeVertexPositionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); var cubesize = 0.005f; var vertices = new[]{ // Front face -cubesize, -cubesize, cubesize, cubesize, -cubesize, cubesize, cubesize, cubesize, cubesize, -cubesize, cubesize, cubesize, // Back face -cubesize, -cubesize, -cubesize, -cubesize, cubesize, -cubesize, cubesize, cubesize, -cubesize, cubesize, -cubesize, -cubesize, // Top face -cubesize, cubesize, -cubesize, -cubesize, cubesize, cubesize, cubesize, cubesize, cubesize, cubesize, cubesize, -cubesize, // Bottom face -cubesize, -cubesize, -cubesize, cubesize, -cubesize, -cubesize, cubesize, -cubesize, cubesize, -cubesize, -cubesize, cubesize, // Right face cubesize, -cubesize, -cubesize, cubesize, cubesize, -cubesize, cubesize, cubesize, cubesize, cubesize, -cubesize, cubesize, // Left face -cubesize, -cubesize, -cubesize, -cubesize, -cubesize, cubesize, -cubesize, cubesize, cubesize, -cubesize, cubesize, -cubesize }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); var cubeVertexPositionBuffer_itemSize = 3; var cubeVertexPositionBuffer_numItems = 36; // 216, 191, 18 #region colors1 var colors_orange = new[]{ 1.0f, 0.6f, 0.0f, 1.0f, // Front face 1.0f, 0.6f, 0.0f, 1.0f, // Front face 1.0f, 0.6f, 0.0f, 1.0f, // Front face 1.0f, 0.6f, 0.0f, 1.0f, // Front face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Left face 1.0f, 0.8f, 0.0f, 1.0f, // Left face 1.0f, 0.8f, 0.0f, 1.0f, // Left face 1.0f, 0.8f, 0.0f, 1.0f // Left face }; var cubeVertexColorBuffer_orange = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer_orange); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors_orange), gl.STATIC_DRAW); #endregion #region colors2 var colors2 = new[]{ 0.0f, 0.6f, 1.0f, 1.0f, // Front face 0.0f, 0.6f, 1.0f, 1.0f, // Front face 0.0f, 0.6f, 1.0f, 1.0f, // Front face 0.0f, 0.6f, 1.0f, 1.0f, // Front face 0.0f, 0.4f, 0.8f, 1.0f, // Back face 0.0f, 0.4f, 0.8f, 1.0f, // Back face 0.0f, 0.4f, 0.8f, 1.0f, // Back face 0.0f, 0.4f, 0.8f, 1.0f, // Back face 0.0f, 0.5f, 0.9f, 1.0f, // Top face 0.0f, 0.5f, 0.9f, 1.0f, // Top face 0.0f, 0.5f, 0.9f, 1.0f, // Top face 0.0f, 0.5f, 0.9f, 1.0f, // Top face 0.0f, 0.5f, 1.0f, 1.0f, // Bottom face 0.0f, 0.5f, 1.0f, 1.0f, // Bottom face 0.0f, 0.5f, 1.0f, 1.0f, // Bottom face 0.0f, 0.5f, 1.0f, 1.0f, // Bottom face 0.0f, 0.8f, 1.0f, 1.0f, // Right face 0.0f, 0.8f, 1.0f, 1.0f, // Right face 0.0f, 0.8f, 1.0f, 1.0f, // Right face 0.0f, 0.8f, 1.0f, 1.0f, // Right face 0.0f, 0.8f, 1.0f, 1.0f, // Left face 0.0f, 0.8f, 1.0f, 1.0f, // Left face 0.0f, 0.8f, 1.0f, 1.0f, // Left face 0.0f, 0.8f, 1.0f, 1.0f // Left face }; var cubeVertexColorBuffer2 = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer2); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors2), gl.STATIC_DRAW); #endregion #region colors3 var colors_green = new[]{ 0.0f, 1.0f, 0.0f, 1.0f, // Front face 0.0f, 1.0f, 0.0f, 1.0f, // Front face 0.0f, 1.0f, 0.0f, 1.0f, // Front face 0.0f, 1.0f, 0.0f, 1.0f, // Front face 0.0f, 0.4f, 0.0f, 1.0f, // Back face 0.0f, 0.4f, 0.0f, 1.0f, // Back face 0.0f, 0.4f, 0.0f, 1.0f, // Back face 0.0f, 0.4f, 0.0f, 1.0f, // Back face 0.0f, 0.5f, 0.0f, 1.0f, // Top face 0.0f, 0.5f, 0.0f, 1.0f, // Top face 0.0f, 0.5f, 0.0f, 1.0f, // Top face 0.0f, 0.5f, 0.0f, 1.0f, // Top face 0.0f, 0.7f, 0.0f, 1.0f, // Bottom face 0.0f, 0.7f, 0.0f, 1.0f, // Bottom face 0.0f, 0.7f, 0.0f, 1.0f, // Bottom face 0.0f, 0.7f, 0.0f, 1.0f, // Bottom face 0.0f, 0.8f, 0.0f, 1.0f, // Right face 0.0f, 0.8f, 0.0f, 1.0f, // Right face 0.0f, 0.8f, 0.0f, 1.0f, // Right face 0.0f, 0.8f, 0.0f, 1.0f, // Right face 0.0f, 0.9f, 0.0f, 1.0f, // Left face 0.0f, 0.9f, 0.0f, 1.0f, // Left face 0.0f, 0.9f, 0.0f, 1.0f, // Left face 0.0f, 0.9f, 0.0f, 1.0f // Left face }; var cubeVertexColorBuffer_green = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer_green); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors_green), gl.STATIC_DRAW); #endregion #region colors_black var colors_black = new[]{ 0.0f, 0.0f, 0.0f, 1.0f, // Front face 0.0f, 0.0f, 0.0f, 1.0f, // Front face 0.0f, 0.0f, 0.0f, 1.0f, // Front face 0.0f, 0.0f, 0.0f, 1.0f, // Front face 0.0f, 0.0f, 0.0f, 1.0f, // Back face 0.0f, 0.0f, 0.0f, 1.0f, // Back face 0.0f, 0.0f, 0.0f, 1.0f, // Back face 0.0f, 0.0f, 0.0f, 1.0f, // Back face 0.0f, 0.0f, 0.0f, 1.0f, // Top face 0.0f, 0.0f, 0.0f, 1.0f, // Top face 0.0f, 0.0f, 0.0f, 1.0f, // Top face 0.0f, 0.0f, 0.0f, 1.0f, // Top face 0.0f, 0.0f, 0.0f, 1.0f, // Bottom face 0.0f, 0.0f, 0.0f, 1.0f, // Bottom face 0.0f, 0.0f, 0.0f, 1.0f, // Bottom face 0.0f, 0.0f, 0.0f, 1.0f, // Bottom face 0.0f, 0.0f, 0.0f, 1.0f, // Right face 0.0f, 0.0f, 0.0f, 1.0f, // Right face 0.0f, 0.0f, 0.0f, 1.0f, // Right face 0.0f, 0.0f, 0.0f, 1.0f, // Right face 0.0f, 0.0f, 0.0f, 1.0f, // Left face 0.0f, 0.0f, 0.0f, 1.0f, // Left face 0.0f, 0.0f, 0.0f, 1.0f, // Left face 0.0f, 0.0f, 0.0f, 1.0f // Left face }; var cubeVertexColorBuffer_black = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer_black); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors_black), gl.STATIC_DRAW); #endregion var cubeVertexColorBuffer_itemSize = 4; var cubeVertexColorBuffer_numItems = 24; var cubeVertexIndexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); var cubeVertexIndices = new UInt16[]{ 0, 1, 2, 0, 2, 3, // Front face 4, 5, 6, 4, 6, 7, // Back face 8, 9, 10, 8, 10, 11, // Top face 12, 13, 14, 12, 14, 15, // Bottom face 16, 17, 18, 16, 18, 19, // Right face 20, 21, 22, 20, 22, 23 // Left face }; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW); var cubeVertexIndexBuffer_itemSize = 1; var cubeVertexIndexBuffer_numItems = 36; #endregion #endregion gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); gl.enable(gl.DEPTH_TEST); var IsWalking = false; var WalkMultiplier = 0.0f; var ego_x = 0f; var ego_y = 0f; var ego_z = 0f; var ego_za = 0f; var rCube = 0f; var raCube = 0f; var lastTime = 0L; Action animate = delegate { var timeNow = new IDate().getTime(); if (lastTime != 0) { var elapsed = timeNow - lastTime; var u = ego_z + ego_za * (elapsed) / 1000.0f; // script: error JSC1000: No implementation found for this native method, please implement [static System.Math.Min(System.Single, System.Single)] if (u < 0) ego_z = (float)Math.Min((double)ego_z, (double)0); else ego_z = u; ego_za -= 3.2f * (elapsed) / 1000.0f; raCube += (75 * elapsed) / 1000.0f; } lastTime = timeNow; }; Func<float, float> degToRad = (degrees) => { return degrees * (f)Math.PI / 180f; }; var c = 0; #region drawScene Action drawScene = delegate { if (ego_x < 0) ego_x = 0; if (ego_y > 0) ego_y = 0; gl.viewport(0, 0, gl_viewportWidth, gl_viewportHeight); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); __glMatrix.mat4.perspective(45f, (float)gl_viewportWidth / (float)gl_viewportHeight, 0.1f, 100.0f, pMatrix); __glMatrix.mat4.identity(mvMatrix); #region vertex gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); gl.vertexAttribPointer((ulong)shaderProgram_vertexPositionAttribute, cubeVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); #endregion //__glMatrix.mat4.rotate(mvMatrix, degToRad(-33), new float[] { 0f, 1f, 0f }); //__glMatrix.mat4.rotate(mvMatrix, rCube, new float[] { 1f, 0f, 0f }); #region OriginalCubeAt Action<float, float, float> OriginalCubeAt = (x, y, z) => { mvMatrixScope( delegate { __glMatrix.mat4.translate(mvMatrix, new float[] { x, y, z }); __glMatrix.mat4.rotate(mvMatrix, degToRad(raCube), new float[] { 1f, 1f, 1f }); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); setMatrixUniforms(); gl.drawElements(gl.TRIANGLES, cubeVertexPositionBuffer_numItems, gl.UNSIGNED_SHORT, 0); } ); }; #endregion mvMatrixScope( delegate { __glMatrix.mat4.translate(mvMatrix, new float[] { - 1.5f, 0, - 7f}); __glMatrix.mat4.rotate(mvMatrix, degToRad(-80), new float[] { 1f, 0f, 0f }); #region grid #region color gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer_green); gl.vertexAttribPointer((ulong)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); #endregion var GridZoom = 0.3f; Action<float> WriteYLine = x => { for (int i = -12; i < -1; i++) { OriginalCubeAt(x * GridZoom, (i) * GridZoom, 0); } }; for (int i = 1; i < 12; i++) WriteYLine(i); #region color gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer_orange); gl.vertexAttribPointer((ulong)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); #endregion for (int i = 1; i < 12; i++) OriginalCubeAt(i * GridZoom, 0, 0); for (int i = -12; i < 0; i++) OriginalCubeAt(0, (i) * GridZoom, 0); #endregion #region color gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer2); gl.vertexAttribPointer((ulong)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); #endregion { var _y = (float)Math.Cos(raCube * 0.05f) * 0.1f; var _x = (float)Math.Sin(raCube * 0.05f) * 0.1f; OriginalCubeAt(_x, _y, 0); } { var _y = (float)Math.Sin(rCube) * 0.2f; var _x = (float)Math.Cos(rCube) * 0.2f; OriginalCubeAt(_x, _y, 0); } mvMatrixScope( delegate { // where are we __glMatrix.mat4.translate(mvMatrix, new float[] { ego_x, ego_y, ego_z }); // rotate all of it //__glMatrix.mat4.rotate(mvMatrix, degToRad(-45), new float[] { 1f, 0f, 0f }); // which way are we looking at? __glMatrix.mat4.rotate(mvMatrix, rCube, new float[] { 0f, 0f, 1f }); #region cube Action<float, float, float> cube = (x, y, z) => { mvPushMatrix(); __glMatrix.mat4.translate(mvMatrix, new float[] { 2 * cubesize * x, 2 * cubesize * y, 2 * cubesize * z}); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); setMatrixUniforms(); gl.drawElements(gl.TRIANGLES, cubeVertexPositionBuffer_numItems, gl.UNSIGNED_SHORT, 0); mvPopMatrix(); }; #endregion cube #region draw Action<int, int, int> rect = (ix, iy, z) => { for (int y = 0; y < ix; y++) { for (int x = 0; x < iy; x++) { cube(x, y, z); } } }; #endregion draw #region leg Action<int, float, float> leg = (y, hiprotation, kneerotation) => { mvPushMatrix(); #region hiprotation __glMatrix.mat4.translate(mvMatrix, new float[] { 2 * cubesize * 2, 2 * cubesize * 0, 2 * cubesize * 11}); __glMatrix.mat4.rotate(mvMatrix, degToRad(hiprotation), new float[] { 0f, 1f, 0f }); __glMatrix.mat4.translate(mvMatrix, new float[] { 2 * cubesize * -2, 2 * cubesize * 0, 2 * cubesize * -11}); #endregion __glMatrix.mat4.translate(mvMatrix, new float[] { 2 * cubesize * 1, 2 * cubesize * y, 2 * cubesize * 0}); mvPushMatrix(); #region kneerotation __glMatrix.mat4.translate(mvMatrix, new float[] { 2 * cubesize * 1, 2 * cubesize * 0, 2 * cubesize * 6f}); __glMatrix.mat4.rotate(mvMatrix, degToRad(kneerotation), new float[] { 0f, 1f, 0f }); __glMatrix.mat4.translate(mvMatrix, new float[] { 2 * cubesize * -1, 2 * cubesize * 0, 2 * cubesize * -6f}); #endregion #region color gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer_orange); gl.vertexAttribPointer((ulong)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); #endregion #region lower leg rect(3, 5, 0); rect(3, 5, 1); rect(3, 5, 2); rect(3, 3, 3); #endregion #region color gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer2); gl.vertexAttribPointer((ulong)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); #endregion rect(3, 3, 4); rect(3, 3, 5); rect(3, 3, 6); mvPopMatrix(); #region upper leg mvPushMatrix(); __glMatrix.mat4.translate(mvMatrix, new float[] { 2 * cubesize * 1, 2 * cubesize * 0, 2 * cubesize * 0}); rect(3, 3, 7); rect(3, 3, 8); rect(3, 3, 9); mvPopMatrix(); #endregion #region hips rect(3, 4, 10); //rect(3, 4, 11); #endregion mvPopMatrix(); }; #endregion var seed = (raCube * WalkMultiplier * 16); #region animated_leg Action<int, int> animated_leg = (seed_offset, x) => { var seed_180 = (float)((seed + seed_offset) % 180f); var left_hip = 30f; var left_knee = 0f; if (ego_z < 0) { // crouch left_hip = -66; left_knee = left_hip * -2; } else if (ego_z > 0) { // crouch left_hip = 10; left_knee = 10; } else if (!IsWalking) { left_hip = 0; left_knee = 0; } else { left_hip = seed_180; if (left_hip > 90) { left_hip = 180 - left_hip; // -60 should be 0 - front // 0 should be 60 // 30 should be 0 - back var v = (90 - left_hip) - 70; if (v < 0) left_knee = 70 + v; else if (v == 0) left_knee = 70; else if (v > 0) left_knee = (20 - v) * (70 / 20); //page.Data1.innerText = "" + new { left_hip, v, left_knee }; } else { } left_hip -= 45; } leg(x, left_hip, left_knee); }; #endregion animated_leg(0, -2); animated_leg(90, 128 - 5); #region body mvMatrixScope( delegate { __glMatrix.mat4.translate(mvMatrix, new float[] { 2 * cubesize * 1, 2 * cubesize * -2, 2 * cubesize * 11}); rect(128, 128, 0); } ); #endregion } ); } ); }; drawScene(); #endregion #region requestAnimFrame var requestAnimFrame = (IFunction)new IFunction( @"return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(/* function FrameRequestCallback */ callback, /* DOMElement Element */ element) { window.setTimeout(callback, 1000/60); };" ).apply(null); #endregion #region tick - new in lesson 03 var tick = default(Action); tick = delegate { c++; Native.Document.title = "" + c + " " + (rCube) + " " + ego_z + " " + ego_za; drawScene(); animate(); requestAnimFrame.apply(null, IFunction.OfDelegate(tick)); }; tick(); #endregion #region onkeyup Native.Document.body.onkeyup += (e) => { //Native.Document.title = "" + new { e.KeyCode }; if (e.KeyCode == 17) { ego_z = 0; } if (e.KeyCode == 32) { ego_z = 0; ego_za = 2; } if (e.KeyCode == 38) { IsWalking = false; } if (e.KeyCode == 40) { IsWalking = false; } }; #endregion #region onkeydown Native.Document.body.onkeydown += (e) => { // see also: http://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes e.PreventDefault(); #region turnspeed var turnspeed = 0.05f; if (e.KeyCode == 37) { // left rCube += turnspeed; } if (e.KeyCode == 65) { // left rCube += turnspeed; } if (e.KeyCode == 39) { rCube -= turnspeed; // right } if (e.KeyCode == 68) { rCube -= turnspeed; // right } #endregion if (e.KeyCode == 17) { ego_z = -cubesize * 6; } if (e.KeyCode == 32) { ego_z = -cubesize * 6; } if (ego_z > 0) { // not on ground. cant walk :) } else { if (e.KeyCode == 38) { IsWalking = true; // mat aint working .. if (!e.shiftKey) { WalkMultiplier = 0.04f; } else { WalkMultiplier = 0.02f; } ego_y += (float)Math.Sin(rCube) * WalkMultiplier; ego_x += (float)Math.Cos(rCube) * WalkMultiplier; } if (e.KeyCode == 40) { IsWalking = true; WalkMultiplier = 0.02f; ego_y -= (float)Math.Sin(rCube) * WalkMultiplier; ego_x -= (float)Math.Cos(rCube) * WalkMultiplier; } } }; #endregion }
/// <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 size = 500; var gl = new WebGLRenderingContext(); var canvas = gl.canvas.AttachToDocument(); Native.document.body.style.overflow = IStyle.OverflowEnum.hidden; canvas.style.SetLocation(0, 0, size, size); canvas.width = size; canvas.height = size; var gl_viewportWidth = size; var gl_viewportHeight = size; #region IsDisposed var IsDisposed = false; this.Dispose = delegate { if (IsDisposed) return; IsDisposed = true; canvas.Orphanize(); }; #endregion #region AtResize Action AtResize = delegate { gl_viewportWidth = Native.window.Width; gl_viewportHeight = Native.window.Height; canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportHeight); canvas.width = gl_viewportWidth; canvas.height = gl_viewportHeight; }; Native.window.onresize += e => { AtResize(); }; AtResize(); #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 #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 shaderProgram = gl.createProgram(); var vs = createShader(new GeometryVertexShader()); var fs = createShader(new GeometryFragmentShader()); gl.attachShader(shaderProgram, vs); gl.attachShader(shaderProgram, fs); gl.linkProgram(shaderProgram); gl.useProgram(shaderProgram); var shaderProgram_vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); gl.enableVertexAttribArray((uint)shaderProgram_vertexPositionAttribute); // new in lesson 02 var shaderProgram_vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor"); gl.enableVertexAttribArray((uint)shaderProgram_vertexColorAttribute); var shaderProgram_pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); var shaderProgram_mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); var mvMatrix = glMatrix.mat4.create(); var mvMatrixStack = new Stack<Float32Array>(); var pMatrix = glMatrix.mat4.create(); #region new in lesson 03 Action mvPushMatrix = delegate { var copy = glMatrix.mat4.create(); glMatrix.mat4.set(mvMatrix, copy); mvMatrixStack.Push(copy); }; Action mvPopMatrix = delegate { mvMatrix = mvMatrixStack.Pop(); }; #endregion #region setMatrixUniforms Action setMatrixUniforms = delegate { gl.uniformMatrix4fv(shaderProgram_pMatrixUniform, false, pMatrix); gl.uniformMatrix4fv(shaderProgram_mvMatrixUniform, false, mvMatrix); }; #endregion #region init buffers var triangleVertexPositionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer); var vertices = new[]{ 0.0f, 1.0f, 0.0f, -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); var triangleVertexPositionBuffer_itemSize = 3; var triangleVertexPositionBuffer_numItems = 3; #region new in lesson 02 var triangleVertexColorBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexColorBuffer); var colors = new[]{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW); var triangleVertexColorBuffer_itemSize = 4; var triangleVertexColorBuffer_numItems = 3; #endregion var squareVertexPositionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer); vertices = new[]{ 1.0f, 1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 1.0f, -1.0f, 0.0f, -1.0f, -1.0f, 0.0f }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); var squareVertexPositionBuffer_itemSize = 3; var squareVertexPositionBuffer_numItems = 4; #region new in lesson 02 var squareVertexColorBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexColorBuffer); #region loop unrolled :) colors = new[]{ 0.5f, 0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 1.0f, 1.0f }; #endregion gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW); var squareVertexColorBuffer_itemSize = 4; var squareVertexColorBuffer_numItems = 4; #endregion #endregion gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); gl.enable(gl.DEPTH_TEST); #region new in lesson 03 var rTri = 0f; var rSquare = 0f; var lastTime = 0L; Action animate = delegate { var timeNow = new IDate().getTime(); if (lastTime != 0) { var elapsed = timeNow - lastTime; rTri += (90 * elapsed) / 1000.0f; rSquare += (75 * elapsed) / 1000.0f; } lastTime = timeNow; }; Func<float, float> degToRad = (degrees) => { return degrees * (f)Math.PI / 180f; }; #endregion #region drawScene Action drawScene = delegate { gl.viewport(0, 0, gl_viewportWidth, gl_viewportHeight); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); glMatrix.mat4.perspective(45f, (float)gl_viewportWidth / (float)gl_viewportHeight, 0.1f, 100.0f, pMatrix); glMatrix.mat4.identity(mvMatrix); glMatrix.mat4.translate(mvMatrix, new float[] { -1.5f, 0.0f, -7.0f }); #region new in lesson 03 mvPushMatrix(); // we’re changing our current rotation state as stored in the model-view matrix // MVC? :) glMatrix.mat4.rotate(mvMatrix, degToRad(rTri), new float[] { 0f, 1f, 0f }); #endregion gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, triangleVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); #region new in lesson 02 gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexColorBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, triangleVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); #endregion setMatrixUniforms(); gl.drawArrays(gl.TRIANGLES, 0, triangleVertexPositionBuffer_numItems); #region new in lesson 03 mvPopMatrix(); #endregion glMatrix.mat4.translate(mvMatrix, new float[] { 3.0f, 0.0f, 0.0f }); #region new in lesson 03 mvPushMatrix(); glMatrix.mat4.rotate(mvMatrix, degToRad(rSquare), new float[] { 1f, 0f, 0f }); #endregion gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, squareVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); #region new in lesson 02 gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexColorBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, squareVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); #endregion setMatrixUniforms(); gl.drawArrays(gl.TRIANGLE_STRIP, 0, squareVertexPositionBuffer_numItems); #region new in lesson 03 mvPopMatrix(); #endregion }; drawScene(); #endregion var c = 0; Native.window.onframe += delegate { c++; //Native.Document.title = "" + c; drawScene(); animate(); }; 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.style.color = "yellow"; 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) { // works in IE11 style.Content.AttachToHead(); 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_viewportHeight); canvas.width = gl_viewportWidth; canvas.height = gl_viewportHeight; #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 #region init shaders var shaderProgram = gl.createProgram( new Shaders.GeometryVertexShader(), new Shaders.GeometryFragmentShader() ); gl.linkProgram(shaderProgram); gl.useProgram(shaderProgram); #region getAttribLocation Func<string, long> getAttribLocation = name => gl.getAttribLocation(shaderProgram, name); #endregion #region getUniformLocation Func<string, WebGLUniformLocation> getUniformLocation = name => gl.getUniformLocation(shaderProgram, name); #endregion #endregion var shaderProgram_vertexPositionAttribute = getAttribLocation("aVertexPosition"); gl.enableVertexAttribArray((uint)shaderProgram_vertexPositionAttribute); var shaderProgram_textureCoordAttribute = getAttribLocation("aTextureCoord"); gl.enableVertexAttribArray((uint)shaderProgram_textureCoordAttribute); var shaderProgram_pMatrixUniform = getUniformLocation("uPMatrix"); var shaderProgram_mvMatrixUniform = getUniformLocation("uMVMatrix"); var shaderProgram_samplerUniform = getUniformLocation("uSampler"); var mvMatrix = glMatrix.mat4.create(); var mvMatrixStack = new Stack<Float32Array>(); var pMatrix = glMatrix.mat4.create(); #region mvPushMatrix Action mvPushMatrix = delegate { var copy = glMatrix.mat4.create(); glMatrix.mat4.set(mvMatrix, copy); mvMatrixStack.Push(copy); }; #endregion #region mvPopMatrix Action mvPopMatrix = delegate { mvMatrix = mvMatrixStack.Pop(); }; #endregion #region setMatrixUniforms Action setMatrixUniforms = delegate { gl.uniformMatrix4fv(shaderProgram_pMatrixUniform, false, pMatrix); gl.uniformMatrix4fv(shaderProgram_mvMatrixUniform, false, mvMatrix); }; #endregion #region degToRad Func<float, float> degToRad = (degrees) => { return degrees * (f)Math.PI / 180f; }; Func<float, float> radToDeg = (rad) => { return rad * 180f / (f)Math.PI; }; #endregion var pitch = 0f; var pitchRate = 0f; var yaw = 0f; var yawRate = 0f; var xPos = 0f; var yPos = 0.4f; var zPos = 0f; var speed = 0f; #region currentlyPressedKeys var currentlyPressedKeys = new Dictionary<int, bool> { {33, false}, {34, false}, {37, false}, {39, false}, {38, false}, {40, false}, {83, false}, {87, false}, {65, false}, {68, false}, }; Native.Document.onkeydown += e => { currentlyPressedKeys[e.KeyCode] = true; }; Native.Document.onkeyup += e => { currentlyPressedKeys[e.KeyCode] = false; }; #endregion #region currentlyPressedKeysEitherOf Func<int, int, bool> currentlyPressedKeysEitherOf = (a, b) => { if (currentlyPressedKeys[a]) return true; if (currentlyPressedKeys[b]) return true; return false; }; #endregion #region handleKeys Action handleKeys = delegate { if (currentlyPressedKeys[33]) { // Page Up pitchRate = 0.1f; } else if (currentlyPressedKeys[34]) { // Page Down pitchRate = -0.1f; } else { pitchRate = 0; } if (currentlyPressedKeysEitherOf(37, 65)) { // Left cursor key or A yawRate = 0.1f; } else if (currentlyPressedKeysEitherOf(39, 68)) { // Right cursor key or D yawRate = -0.1f; } else { yawRate = 0; } if (currentlyPressedKeysEitherOf(38, 87)) { // Up cursor key or W speed = 0.003f; } else if (currentlyPressedKeysEitherOf(40, 83)) { // Down cursor key speed = -0.003f; } else { speed = 0; } }; #endregion #region requestPointerLock var __pointer_x = 0; var __pointer_y = 0; canvas.onmousedown += delegate { // http://connect.microsoft.com/IE/feedback/details/793718/ie11-feature-request-support-for-pointer-lock-api canvas.requestPointerLock(); }; canvas.onmousemove += e => { if (Native.document.pointerLockElement == canvas) { __pointer_x += e.movementX; __pointer_y += e.movementY; } }; canvas.onmouseup += delegate { // keep at it... //Native.Document.exitPointerLock(); }; #endregion #region AtResize Action AtResize = delegate { gl_viewportWidth = Native.window.Width; gl_viewportHeight = Native.window.Height; 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 HTML.Images.FromAssets.mud().InvokeOnComplete( mud => { var mudTexture = gl.createTexture(); gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1); gl.bindTexture(gl.TEXTURE_2D, mudTexture); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, mud); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, (int)gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, (int)gl.LINEAR); gl.bindTexture(gl.TEXTURE_2D, null); Func<string, f> parseFloat = x => (f)double.Parse(x); var lines = data.Split('\n'); var vertexCount = 0; var vertexPositions = new List<f>(); var vertexTextureCoords = new List<f>(); foreach (var i in lines) { var vals = i.Trim().Replace(" ", " ").Replace(" ", " ").Split(' '); if (vals.Length == 5) if (vals[0] != "//") { // It is a line describing a vertex; get X, Y and Z first vertexPositions.Add(parseFloat(vals[0])); vertexPositions.Add(parseFloat(vals[1])); vertexPositions.Add(parseFloat(vals[2])); // And then the texture coords vertexTextureCoords.Add(parseFloat(vals[3])); vertexTextureCoords.Add(parseFloat(vals[4])); vertexCount += 1; } } var worldVertexPositionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, worldVertexPositionBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexPositions.ToArray()), gl.STATIC_DRAW); var worldVertexPositionBuffer_itemSize = 3; var worldVertexPositionBuffer_numItems = vertexCount; var worldVertexTextureCoordBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, worldVertexTextureCoordBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexTextureCoords.ToArray()), gl.STATIC_DRAW); var worldVertexTextureCoordBuffer_itemSize = 2; var worldVertexTextureCoordBuffer_numItems = vertexCount; gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); gl.enable(gl.DEPTH_TEST); var lastTime = 0L; // Used to make us "jog" up and down as we move forward. var joggingAngle = 0f; #region animate Action animate = () => { var timeNow = new IDate().getTime(); if (lastTime != 0) { var elapsed = timeNow - lastTime; if (speed != 0) { xPos -= (f)Math.Sin(degToRad(yaw)) * speed * elapsed; zPos -= (f)Math.Cos(degToRad(yaw)) * speed * elapsed; joggingAngle += elapsed * 0.6f; // 0.6 "fiddle factor" - makes it feel more realistic :-) yPos = (f)Math.Sin(degToRad(joggingAngle)) / 20 + 0.4f; } else { joggingAngle += elapsed * 0.06f; // 0.6 "fiddle factor" - makes it feel more realistic :-) yPos = (f)Math.Sin(degToRad(joggingAngle)) / 200 + 0.4f; } yaw += yawRate * elapsed; pitch += pitchRate * elapsed; } lastTime = timeNow; }; #endregion #region drawScene Action drawScene = () => { gl.viewport(0, 0, gl_viewportWidth, gl_viewportHeight); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); glMatrix.mat4.perspective(45, (float)Native.window.aspect, 0.1f, 100.0f, pMatrix); glMatrix.mat4.identity(mvMatrix); if (__pointer_y != 0) pitch = radToDeg(__pointer_y * -0.01f); if (__pointer_x != 0) yaw = radToDeg(__pointer_x * -0.01f); glMatrix.mat4.rotate(mvMatrix, degToRad(-pitch), new f[] { 1, 0, 0 }); glMatrix.mat4.rotate(mvMatrix, degToRad(-yaw), new f[] { 0, 1, 0 }); //glMatrix.mat4.rotate(mvMatrix, __pointer_y * 0.01f, 1, 0, 0); //glMatrix.mat4.rotate(mvMatrix, __pointer_x * 0.01f, 0, 1, 0); glMatrix.mat4.translate(mvMatrix, new[] { -xPos, -yPos, -zPos }); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, mudTexture); gl.uniform1i(shaderProgram_samplerUniform, 0); gl.bindBuffer(gl.ARRAY_BUFFER, worldVertexTextureCoordBuffer); gl.vertexAttribPointer((uint)shaderProgram_textureCoordAttribute, worldVertexTextureCoordBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, worldVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, worldVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); setMatrixUniforms(); gl.drawArrays(gl.TRIANGLES, 0, worldVertexPositionBuffer_numItems); }; #endregion Native.window.onframe += delegate { if (IsDisposed) return; handleKeys(); drawScene(); animate(); }; } ); }
/// <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(); canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportHeight); canvas.width = gl_viewportWidth; canvas.height = gl_viewportHeight; #region toolbar var toolbar = new Toolbar(); if (page != null) { toolbar.Container.AttachToDocument(); toolbar.Container.style.Opacity = 0.7; toolbar.HideButton.onclick += delegate { // ScriptCoreLib.Extensions toolbar.HideTarget.ToggleVisible(); }; } #endregion #region IsDisposed var IsDisposed = false; this.Dispose = delegate { if (IsDisposed) return; IsDisposed = true; canvas.Orphanize(); }; #endregion #region AtResize Action AtResize = delegate { gl_viewportWidth = Native.window.Width; gl_viewportHeight = Native.window.Height; canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportHeight); canvas.width = gl_viewportWidth; canvas.height = gl_viewportHeight; }; Native.window.onresize += e => { AtResize(); }; AtResize(); #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 shaderProgram = gl.createProgram( new GeometryVertexShader(), new GeometryFragmentShader() ); gl.linkProgram(shaderProgram); gl.useProgram(shaderProgram); var shaderProgram_vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); gl.enableVertexAttribArray((uint)shaderProgram_vertexPositionAttribute); // new in lesson 02 var shaderProgram_vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor"); gl.enableVertexAttribArray((uint)shaderProgram_vertexColorAttribute); var shaderProgram_pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); var shaderProgram_mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); var mvMatrix = glMatrix.mat4.create(); var mvMatrixStack = new Stack<Float32Array>(); var pMatrix = glMatrix.mat4.create(); #region new in lesson 03 Action mvPushMatrix = delegate { var copy = glMatrix.mat4.create(); glMatrix.mat4.set(mvMatrix, copy); mvMatrixStack.Push(copy); }; Action mvPopMatrix = delegate { mvMatrix = mvMatrixStack.Pop(); }; #endregion #region setMatrixUniforms Action setMatrixUniforms = delegate { gl.uniformMatrix4fv(shaderProgram_pMatrixUniform, false, pMatrix); gl.uniformMatrix4fv(shaderProgram_mvMatrixUniform, false, mvMatrix); }; #endregion #region cube var cubeVertexPositionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); var cubesize = 1.0f * 0.10f; var vertices = new[]{ // Front face -cubesize, -cubesize, cubesize, cubesize, -cubesize, cubesize, cubesize, cubesize, cubesize, -cubesize, cubesize, cubesize, // Back face -cubesize, -cubesize, -cubesize, -cubesize, cubesize, -cubesize, cubesize, cubesize, -cubesize, cubesize, -cubesize, -cubesize, // Top face -cubesize, cubesize, -cubesize, -cubesize, cubesize, cubesize, cubesize, cubesize, cubesize, cubesize, cubesize, -cubesize, // Bottom face -cubesize, -cubesize, -cubesize, cubesize, -cubesize, -cubesize, cubesize, -cubesize, cubesize, -cubesize, -cubesize, cubesize, // Right face cubesize, -cubesize, -cubesize, cubesize, cubesize, -cubesize, cubesize, cubesize, cubesize, cubesize, -cubesize, cubesize, // Left face -cubesize, -cubesize, -cubesize, -cubesize, -cubesize, cubesize, -cubesize, cubesize, cubesize, -cubesize, cubesize, -cubesize }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); var cubeVertexPositionBuffer_itemSize = 3; var cubeVertexPositionBuffer_numItems = 36; var cubeVertexColorBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer); // 216, 191, 18 var colors = new[]{ 1.0f, 0.6f, 0.0f, 1.0f, // Front face 1.0f, 0.6f, 0.0f, 1.0f, // Front face 1.0f, 0.6f, 0.0f, 1.0f, // Front face 1.0f, 0.6f, 0.0f, 1.0f, // Front face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Left face 1.0f, 0.8f, 0.0f, 1.0f, // Left face 1.0f, 0.8f, 0.0f, 1.0f, // Left face 1.0f, 0.8f, 0.0f, 1.0f // Left face }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW); var cubeVertexColorBuffer_itemSize = 4; var cubeVertexColorBuffer_numItems = 24; var cubeVertexIndexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); var cubeVertexIndices = new UInt16[]{ 0, 1, 2, 0, 2, 3, // Front face 4, 5, 6, 4, 6, 7, // Back face 8, 9, 10, 8, 10, 11, // Top face 12, 13, 14, 12, 14, 15, // Bottom face 16, 17, 18, 16, 18, 19, // Right face 20, 21, 22, 20, 22, 23 // Left face }; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW); var cubeVertexIndexBuffer_itemSize = 1; var cubeVertexIndexBuffer_numItems = 36; #endregion gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); gl.enable(gl.DEPTH_TEST); #region new in lesson 04 var rPyramid = 0f; var rCube = 0f; var lastTime = 0L; Action animate = delegate { var timeNow = new IDate().getTime(); if (lastTime != 0) { var elapsed = timeNow - lastTime; rPyramid += (90 * elapsed) / 1000.0f; rCube -= (75 * elapsed) / 1000.0f; } lastTime = timeNow; }; Func<float, float> degToRad = (degrees) => { return degrees * (f)Math.PI / 180f; }; #endregion // jsc error //var fdeg_state = new float[5]; var fdeg_state = new int[5]; // int array not initialized? fdeg_state[0] = 0; fdeg_state[1] = 66; fdeg_state[2] = 66; fdeg_state[3] = 0; fdeg_state[4] = 66; var fdeg_relax = new int[5]; fdeg_relax[0] = 0; fdeg_relax[1] = 0; fdeg_relax[2] = 0; fdeg_relax[3] = 0; fdeg_relax[4] = 0; var fdeg_relaxstate = new int[5]; fdeg_relaxstate[0] = 11; fdeg_relaxstate[1] = 11; fdeg_relaxstate[2] = 11; fdeg_relaxstate[3] = 11; fdeg_relaxstate[4] = 33; 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(); }; #region drawScene Action drawScene = delegate { gl.viewport(0, 0, gl_viewportWidth, gl_viewportHeight); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); glMatrix.mat4.perspective(45f, (float)gl_viewportWidth / (float)gl_viewportHeight, 0.1f, 100.0f, pMatrix); glMatrix.mat4.identity(mvMatrix); #region vertex gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, cubeVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); #endregion #region color gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); #endregion glMatrix.mat4.translate(mvMatrix, new float[] { -1.5f, 0.0f, -7.0f }); mvPushMatrix(); // rotate all of it glMatrix.mat4.rotate(mvMatrix, degToRad(rCube * 0.05f), new float[] { -1f, 0.5f, 0f }); glMatrix.mat4.rotate(mvMatrix, __pointer_y * 0.01f, new float[] { 1f, 0, 0f }); glMatrix.mat4.rotate(mvMatrix, __pointer_x * 0.01f, new float[] { 0, 1f, 0f }); #region DrawCubeAt Action<float, float> DrawCubeAt = (x, y) => { mvPushMatrix(); glMatrix.mat4.translate(mvMatrix, new float[] { 2 * cubesize * x, 2 * cubesize * -y, 0 }); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); setMatrixUniforms(); gl.drawElements(gl.TRIANGLES, cubeVertexPositionBuffer_numItems, gl.UNSIGNED_SHORT, 0); mvPopMatrix(); }; #endregion for (int ix = 0; ix < 11; ix++) { for (int iy = 0; iy < 11; iy++) { DrawCubeAt(ix, iy); } } #region DrawFinger Action<int, float> DrawFinger = (x, fdeg) => { mvPushMatrix(); glMatrix.mat4.rotate(mvMatrix, degToRad(fdeg), new float[] { 1f, 0f, 0f }); // 01.34.67.89.01 DrawCubeAt(3 * x + 0, -2); DrawCubeAt(3 * x + 1, -2); DrawCubeAt(3 * x + 0, -3); DrawCubeAt(3 * x + 1, -3); mvPushMatrix(); glMatrix.mat4.translate(mvMatrix, new float[] { 0, 2 * cubesize * (5), 0 }); glMatrix.mat4.rotate(mvMatrix, degToRad(fdeg), new float[] { 1f, 0f, 0f }); glMatrix.mat4.translate(mvMatrix, new float[] { 0, 2 * cubesize * (-5), 0 }); DrawCubeAt(3 * x + 0, -5); DrawCubeAt(3 * x + 1, -5); DrawCubeAt(3 * x + 0, -6); DrawCubeAt(3 * x + 1, -6); mvPushMatrix(); glMatrix.mat4.translate(mvMatrix, new float[] { 0, 2 * cubesize * (8), 0 }); glMatrix.mat4.rotate(mvMatrix, degToRad(fdeg), new float[] { 1f, 0f, 0f }); glMatrix.mat4.translate(mvMatrix, new float[] { 0, 2 * cubesize * (-8), 0 }); DrawCubeAt(3 * x + 0, -8); DrawCubeAt(3 * x + 1, -8); DrawCubeAt(3 * x + 0, -9); DrawCubeAt(3 * x + 1, -9); mvPopMatrix(); mvPopMatrix(); mvPopMatrix(); }; #endregion // pinky DrawFinger(0, fdeg_state[0]); DrawFinger(1, fdeg_state[1]); // middle DrawFinger(2, fdeg_state[2]); // index DrawFinger(3, fdeg_state[3]); mvPushMatrix(); glMatrix.mat4.rotate(mvMatrix, degToRad(-90), new float[] { 0f, 0f, 1f }); // we have misplaced it now. lets put it into its place:) glMatrix.mat4.translate(mvMatrix, new float[] { 2 * cubesize * -4, 2 * cubesize * 11, 0 }); // the thumb DrawFinger(4, fdeg_state[4]); mvPopMatrix(); mvPopMatrix(); #region original cube glMatrix.mat4.translate(mvMatrix, new float[] { 3.0f, 0.0f, 0.0f }); mvPushMatrix(); glMatrix.mat4.rotate(mvMatrix, degToRad(rCube), new float[] { 1f, 1f, 1f }); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); setMatrixUniforms(); gl.drawElements(gl.TRIANGLES, cubeVertexPositionBuffer_numItems, gl.UNSIGNED_SHORT, 0); mvPopMatrix(); #endregion }; drawScene(); #endregion var c = 0; #region pinky toolbar.f0.onmousedown += delegate { toolbar.f0.style.color = Color.Blue; fdeg_state[0] = 80; fdeg_relax[0] = 0; }; toolbar.f0.onmouseup += delegate { toolbar.f0.style.color = Color.None; //fdeg_state[0] = 11; fdeg_relax[0] = 1; }; #endregion #region finger toolbar.f1.onmousedown += delegate { toolbar.f0.style.color = Color.Blue; fdeg_state[1] = 80; fdeg_relax[1] = 0; }; toolbar.f1.onmouseup += delegate { toolbar.f1.style.color = Color.None; fdeg_relax[1] = 1; }; #endregion #region middle toolbar.f2.onmousedown += delegate { toolbar.f0.style.color = Color.Blue; fdeg_state[2] = 80; fdeg_relax[2] = 0; }; toolbar.f2.onmouseup += delegate { toolbar.f1.style.color = Color.None; fdeg_relax[2] = 1; }; #endregion #region index toolbar.f3.onmousedown += delegate { toolbar.f3.style.color = Color.Blue; fdeg_state[3] = 80; fdeg_relax[3] = 0; }; toolbar.f3.onmouseup += delegate { toolbar.f3.style.color = Color.None; fdeg_relax[3] = 1; }; #endregion #region thumb toolbar.f4.onmousedown += delegate { toolbar.f4.style.color = Color.Blue; fdeg_state[4] = 80; fdeg_relax[4] = 0; }; toolbar.f4.onmouseup += delegate { toolbar.f4.style.color = Color.None; fdeg_relax[4] = 1; }; #endregion #region rock toolbar.fRock.onmousedown += delegate { toolbar.fRock.style.color = Color.Blue; fdeg_state[0] = 0; fdeg_state[1] = 77; fdeg_state[2] = 77; fdeg_state[3] = 0; fdeg_state[4] = 77; fdeg_relax[0] = 0; fdeg_relax[1] = 0; fdeg_relax[2] = 0; fdeg_relax[3] = 0; fdeg_relax[4] = 0; }; toolbar.fRock.onmouseup += delegate { toolbar.fRock.style.color = Color.None; fdeg_relax[0] = 1; fdeg_relax[1] = 1; fdeg_relax[2] = 1; fdeg_relax[3] = 1; fdeg_relax[4] = 1; }; #endregion #region fFist toolbar.fFist.onmousedown += delegate { toolbar.fRock.style.color = Color.Blue; fdeg_state[0] = 88; fdeg_state[1] = 88; fdeg_state[2] = 88; fdeg_state[3] = 88; fdeg_state[4] = 88; fdeg_relax[0] = 0; fdeg_relax[1] = 0; fdeg_relax[2] = 0; fdeg_relax[3] = 0; fdeg_relax[4] = 0; }; toolbar.fFist.onmouseup += delegate { toolbar.fFist.style.color = Color.None; fdeg_relax[0] = 1; fdeg_relax[1] = 1; fdeg_relax[2] = 1; fdeg_relax[3] = 1; fdeg_relax[4] = 1; }; #endregion #region electric toolbar.fElectric.onmousedown += delegate { toolbar.fElectric.style.color = Color.Blue; fdeg_state[0] = 0; fdeg_state[1] = 0; fdeg_state[2] = 0; fdeg_state[3] = 0; fdeg_state[4] = 0; fdeg_relax[0] = 0; fdeg_relax[1] = 0; fdeg_relax[2] = 0; fdeg_relax[3] = 0; fdeg_relax[4] = 0; }; toolbar.fElectric.onmouseup += delegate { toolbar.fElectric.style.color = Color.None; fdeg_relax[0] = 1; fdeg_relax[1] = 1; fdeg_relax[2] = 1; fdeg_relax[3] = 1; fdeg_relax[4] = 1; }; #endregion #region fRelax toolbar.fRelax.onclick += delegate { toolbar.fElectric.style.color = Color.None; fdeg_relax[0] = 1; fdeg_relax[1] = 1; fdeg_relax[2] = 1; fdeg_relax[3] = 1; fdeg_relax[4] = 1; }; #endregion Native.window.onframe += delegate { c++; for (int i = 0; i < 5; i++) { if (fdeg_relax[i] > 0) { // Math.Sign(int) does not exist. // next release should have it! var a = (fdeg_state[i] - fdeg_relaxstate[i]); if (a > 4) fdeg_state[i] -= 3; if (a < -4) fdeg_state[i] += 3; } } Native.document.title = "" + c; drawScene(); animate(); }; //new IHTMLAnchor { "drag me" }.AttachTo(Native.document.documentElement).With( // dragme => // { // dragme.style.position = IStyle.PositionEnum.@fixed; // dragme.style.left = "1em"; // dragme.style.bottom = "1em"; // dragme.style.zIndex = 1000; // dragme.AllowToDragAsApplicationPackage(); // } //); }
/* Source: http://www.webspaceinvader.com/2011/09/21/first-try-at-webgl/ */ /// <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 SCREEN_WIDTH = Native.window.Width; var SCREEN_HEIGHT = Native.window.Height; //var ,stats; //var mesh, zmesh, geometry; var mouseX = 0; var mouseY = 0; var windowHalfX = SCREEN_WIDTH / 2; var windowHalfY = SCREEN_HEIGHT / 2; var lastUpdate = new IDate().getTime(); Native.document.body.style.overflow = IStyle.OverflowEnum.hidden; var container = new IHTMLDiv(); container.AttachToDocument(); container.style.SetLocation(0, 0, Native.window.Width, Native.window.Height); var camera = new THREE.PerspectiveCamera(75, Native.window.aspect, 1, 100000); camera.position.z = 50; camera.updateMatrix(); var scene = new THREE.Scene(); // LIGHTS var ambient = new THREE.AmbientLight(0x222222); ambient.position.z = -300; scene.add(ambient); var directionalLight = new THREE.DirectionalLight(0xffeedd); directionalLight.position.set(-1, 0, 1); directionalLight.position.normalize(); scene.add(directionalLight); var dLight = new THREE.DirectionalLight(0xffeedd); dLight.position.set(1, 0, 1); dLight.position.normalize(); scene.add(dLight); // init the WebGL renderer and append it to the Dom var renderer = new THREE.WebGLRenderer(); renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); renderer.autoClear = false; renderer.domElement.AttachTo(container); #region createScene Action<object, f, f, f, f> createScene = (geometry, x, y, z, b) => { //var zmesh = new THREE.Mesh(geometry, new THREE.MeshFaceMaterial()); var zmesh = new THREE.Mesh(geometry); zmesh.position.x = x; zmesh.position.z = y; zmesh.position.y = z; zmesh.scale.x = 5f; zmesh.scale.y = 5f; zmesh.scale.z = 5f; //zmesh.overdraw = true; zmesh.updateMatrix(); scene.add(zmesh); }; #endregion // message: "Unexpected token /" var loader = new THREE.JSONLoader(); Action<object> callbackMale = (geometry) => { createScene(geometry, 90, 50, 0, 105); }; loader.load( url: new invade().Content.src, callback: IFunction.OfDelegate(callbackMale) ); // postprocessing var composer = new THREE.EffectComposer(renderer); var renderModel = new THREE.RenderPass(scene, camera); composer.addPass(renderModel); var effectFilm = new THREE.FilmPass(0.35, 0.50, 2048, false); //( 0.35, 0.75, 2048, false ); effectFilm.renderToScreen = true; composer.addPass(effectFilm); #region IsDisposed var IsDisposed = false; Dispose = delegate { if (IsDisposed) return; IsDisposed = true; renderer.domElement.Orphanize(); }; #endregion #region getFrametime Func<long> getFrametime = () => { var now = new IDate().getTime(); var tdiff = (now - lastUpdate) / 1000; lastUpdate = now; return tdiff; }; #endregion #region render Action render = delegate { var delta = getFrametime(); camera.position.x += (mouseX - camera.position.x) * .05f; camera.position.y += (-mouseY - camera.position.y) * .05f; camera.updateMatrix(); //renderer.render( scene, camera ); renderer.clear(); composer.render(delta); }; #endregion #region onmousemove Native.document.onmousemove += e => { mouseX = (e.CursorX - windowHalfX); mouseY = (e.CursorY - windowHalfY); }; #endregion Native.window.onframe += delegate { if (IsDisposed) return; render(); }; #region AtResize Action AtResize = delegate { container.style.SetLocation(0, 0, Native.window.Width, Native.window.Height); camera.aspect = Native.window.aspect; camera.updateProjectionMatrix(); renderer.setSize(Native.window.Width, Native.window.Height); }; Native.window.onresize += delegate { AtResize(); }; AtResize(); #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 }
/// <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 size = 500; var gl = new WebGLRenderingContext(); var canvas = gl.canvas.AttachToDocument(); Native.document.body.style.overflow = IStyle.OverflowEnum.hidden; canvas.style.SetLocation(0, 0, size, size); canvas.width = size; canvas.height = size; var gl_viewportWidth = size; var gl_viewportHeight = size; var toolbar = new Toolbar(); if (page != null) { toolbar.Container.style.Opacity = 0.7; toolbar.Container.AttachToDocument(); toolbar.HideButton.onclick += delegate { // ScriptCoreLib.Extensions toolbar.HideTarget.ToggleVisible(); }; } #region IsDisposed var IsDisposed = false; this.Dispose = delegate { if (IsDisposed) return; IsDisposed = true; canvas.Orphanize(); }; #endregion #region AtResize Action AtResize = delegate { gl_viewportWidth = Native.window.Width; gl_viewportHeight = Native.window.Height; canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportHeight); canvas.width = gl_viewportWidth; canvas.height = gl_viewportHeight; }; Native.window.onresize += e => { AtResize(); }; AtResize(); #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 #region init shaders var shaderProgram = gl.createProgram( new Shaders.GeometryVertexShader(), new Shaders.GeometryFragmentShader() ); gl.linkProgram(shaderProgram); gl.useProgram(shaderProgram); #region getAttribLocation Func<string, long> getAttribLocation = name => gl.getAttribLocation(shaderProgram, name); #endregion #region getUniformLocation Func<string, WebGLUniformLocation> getUniformLocation = name => gl.getUniformLocation(shaderProgram, name); #endregion #endregion var mvMatrix = glMatrix.mat4.create(); var mvMatrixStack = new Stack<Float32Array>(); var pMatrix = glMatrix.mat4.create(); #region mvPushMatrix Action mvPushMatrix = delegate { var copy = glMatrix.mat4.create(); glMatrix.mat4.set(mvMatrix, copy); mvMatrixStack.Push(copy); }; #endregion #region mvPopMatrix Action mvPopMatrix = delegate { mvMatrix = mvMatrixStack.Pop(); }; #endregion #region degToRad Func<float, float> degToRad = (degrees) => { return degrees * (f)Math.PI / 180f; }; #endregion new HTML.Images.FromAssets.crate().InvokeOnComplete( crate => new HTML.Images.FromAssets.moon().InvokeOnComplete( moon => { var shaderProgram_vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); gl.enableVertexAttribArray((uint)shaderProgram_vertexPositionAttribute); var shaderProgram_textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord"); gl.enableVertexAttribArray((uint)shaderProgram_textureCoordAttribute); var shaderProgram_vertexNormalAttribute = gl.getAttribLocation(shaderProgram, "aVertexNormal"); gl.enableVertexAttribArray((uint)shaderProgram_vertexNormalAttribute); var shaderProgram_pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); var shaderProgram_mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); var shaderProgram_nMatrixUniform = gl.getUniformLocation(shaderProgram, "uNMatrix"); var shaderProgram_samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler"); var shaderProgram_useLightingUniform = gl.getUniformLocation(shaderProgram, "uUseLighting"); var shaderProgram_ambientColorUniform = gl.getUniformLocation(shaderProgram, "uAmbientColor"); var shaderProgram_pointLightingLocationUniform = gl.getUniformLocation(shaderProgram, "uPointLightingLocation"); var shaderProgram_pointLightingColorUniform = gl.getUniformLocation(shaderProgram, "uPointLightingColor"); #region setMatrixUniforms Action setMatrixUniforms = delegate { gl.uniformMatrix4fv(shaderProgram_pMatrixUniform, false, pMatrix); gl.uniformMatrix4fv(shaderProgram_mvMatrixUniform, false, mvMatrix); var normalMatrix = glMatrix.mat3.create(); glMatrix.mat4.toInverseMat3(mvMatrix, normalMatrix); glMatrix.mat3.transpose(normalMatrix); gl.uniformMatrix3fv(shaderProgram_nMatrixUniform, false, normalMatrix); }; #endregion #region cubeVertexPositionBuffer var cubeVertexPositionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); var vertices = new f[] { // Front face -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, // Back face -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, // Top face -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, // Bottom face -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, // Right face 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, // Left face -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); var cubeVertexPositionBuffer_itemSize = 3; var cubeVertexPositionBuffer_numItems = 24; #endregion #region cubeVertexNormalBuffer var cubeVertexNormalBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexNormalBuffer); var vertexNormals = new f[] { // Front face 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, // Back face 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, // Top face 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // Bottom face 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, // Right face 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // Left face -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexNormals), gl.STATIC_DRAW); var cubeVertexNormalBuffer_itemSize = 3; var cubeVertexNormalBuffer_numItems = 24; #endregion #region cubeVertexTextureCoordBuffer var cubeVertexTextureCoordBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexTextureCoordBuffer); var textureCoords = new f[] { // Front face 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, // Back face 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, // Top face 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, // Bottom face 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // Right face 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, // Left face 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoords), gl.STATIC_DRAW); var cubeVertexTextureCoordBuffer_itemSize = 2; #endregion #region cubeVertexIndexBuffer var cubeVertexIndexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); var cubeVertexIndices = new ushort[]{ 0, 1, 2, 0, 2, 3, // Front face 4, 5, 6, 4, 6, 7, // Back face 8, 9, 10, 8, 10, 11, // Top face 12, 13, 14, 12, 14, 15, // Bottom face 16, 17, 18, 16, 18, 19, // Right face 20, 21, 22, 20, 22, 23 // Left face }; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW); var cubeVertexIndexBuffer_itemSize = 1; var cubeVertexIndexBuffer_numItems = 36; #endregion #region moon var latitudeBands = 30; var longitudeBands = 30; var radius = 2; var vertexPositionData = new List<f>(); var normalData = new List<f>(); var textureCoordData = new List<f>(); for (var latNumber = 0; latNumber <= latitudeBands; latNumber++) { var theta = latNumber * Math.PI / latitudeBands; var sinTheta = (f)Math.Sin(theta); var cosTheta = (f)Math.Cos(theta); for (var longNumber = 0; longNumber <= longitudeBands; longNumber++) { var phi = longNumber * 2 * Math.PI / longitudeBands; var sinPhi = (f)Math.Sin(phi); var cosPhi = (f)Math.Cos(phi); var x = cosPhi * sinTheta; var y = cosTheta; var z = sinPhi * sinTheta; var u = 1 - (longNumber / longitudeBands); var v = 1 - (latNumber / latitudeBands); normalData.Add(x); normalData.Add(y); normalData.Add(z); textureCoordData.Add(u); textureCoordData.Add(v); vertexPositionData.Add(radius * x); vertexPositionData.Add(radius * y); vertexPositionData.Add(radius * z); } } var indexData = new List<ushort>(); for (var latNumber = 0; latNumber < latitudeBands; latNumber++) { for (var longNumber = 0; longNumber < longitudeBands; longNumber++) { var first = (latNumber * (longitudeBands + 1)) + longNumber; var second = first + longitudeBands + 1; indexData.Add((ushort)first); indexData.Add((ushort)second); indexData.Add((ushort)(first + 1)); indexData.Add((ushort)second); indexData.Add((ushort)(second + 1)); indexData.Add((ushort)(first + 1)); } } var moonVertexNormalBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexNormalBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(normalData.ToArray()), gl.STATIC_DRAW); var moonVertexNormalBuffer_itemSize = 3; var moonVertexNormalBuffer_numItems = normalData.Count / 3; var moonVertexTextureCoordBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexTextureCoordBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoordData.ToArray()), gl.STATIC_DRAW); var moonVertexTextureCoordBuffer_itemSize = 2; var moonVertexTextureCoordBuffer_numItems = textureCoordData.Count / 2; var moonVertexPositionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexPositionBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexPositionData.ToArray()), gl.STATIC_DRAW); var moonVertexPositionBuffer_itemSize = 3; var moonVertexPositionBuffer_numItems = vertexPositionData.Count / 3; var moonVertexIndexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, moonVertexIndexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexData.ToArray()), gl.STREAM_DRAW); var moonVertexIndexBuffer_itemSize = 1; var moonVertexIndexBuffer_numItems = indexData.Count; #endregion #region handleLoadedTexture Action<WebGLTexture, IHTMLImage> handleLoadedTexture = (texture, texture_image) => { gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1); gl.bindTexture(gl.TEXTURE_2D, texture); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture_image); gl.texParameteri((uint)gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, (int)gl.LINEAR); gl.texParameteri((uint)gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, (int)gl.LINEAR_MIPMAP_NEAREST); gl.generateMipmap(gl.TEXTURE_2D); gl.bindTexture(gl.TEXTURE_2D, null); }; #endregion var moonTexture = gl.createTexture(); handleLoadedTexture(moonTexture, moon); var crateTexture = gl.createTexture(); handleLoadedTexture(crateTexture, crate); gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); gl.enable(gl.DEPTH_TEST); var moonAngle = 180f; var cubeAngle = 0f; var lastTime = 0L; #region animate Action animate = () => { var timeNow = new IDate().getTime(); if (lastTime != 0) { var elapsed = timeNow - lastTime; moonAngle += 0.05f * elapsed; cubeAngle += 0.05f * elapsed; } lastTime = timeNow; }; #endregion //Func<string, f> parseFloat = Convert.ToSingle; Func<string, f> parseFloat = x => float.Parse(x); #region drawScene Action drawScene = () => { gl.viewport(0, 0, gl_viewportWidth, gl_viewportHeight); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); glMatrix.mat4.perspective(45, gl_viewportWidth / gl_viewportHeight, 0.1f, 100.0f, pMatrix); var lighting = toolbar.lighting.@checked; #region [uniform] bool uUseLighting <- lighting gl.uniform1i(shaderProgram_useLightingUniform, Convert.ToInt32(lighting)); #endregion if (lighting) { #region [uniform] vec3 uAmbientColor <- (f ambientR, f ambientG, f ambientB) gl.uniform3f( shaderProgram_ambientColorUniform, parseFloat(toolbar.ambientR.value), parseFloat(toolbar.ambientG.value), parseFloat(toolbar.ambientB.value) ); #endregion #region [uniform] vec3 uPointLightingLocation <- (f lightPositionX, f lightPositionY, f lightPositionZ) gl.uniform3f( shaderProgram_pointLightingLocationUniform, parseFloat(toolbar.lightPositionX.value), parseFloat(toolbar.lightPositionY.value), parseFloat(toolbar.lightPositionZ.value) ); #endregion #region [uniform] vec3 uPointLightingColor <- (f pointR, f pointG, f pointB) gl.uniform3f( shaderProgram_pointLightingColorUniform, parseFloat(toolbar.pointR.value), parseFloat(toolbar.pointG.value), parseFloat(toolbar.pointB.value) ); #endregion } glMatrix.mat4.identity(mvMatrix); glMatrix.mat4.translate(mvMatrix, new f[] { 0, 0, -20 }); #region moon mvPushMatrix(); glMatrix.mat4.rotate(mvMatrix, degToRad(moonAngle), new f[] { 0, 1, 0 }); glMatrix.mat4.translate(mvMatrix, new f[] { 5, 0, 0 }); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, moonTexture); gl.uniform1i(shaderProgram_samplerUniform, 0); gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, moonVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexTextureCoordBuffer); gl.vertexAttribPointer((uint)shaderProgram_textureCoordAttribute, moonVertexTextureCoordBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexNormalBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexNormalAttribute, moonVertexNormalBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, moonVertexIndexBuffer); setMatrixUniforms(); gl.drawElements(gl.TRIANGLES, moonVertexIndexBuffer_numItems, gl.UNSIGNED_SHORT, 0); mvPopMatrix(); #endregion #region cube mvPushMatrix(); glMatrix.mat4.rotate(mvMatrix, degToRad(cubeAngle), new f[] { 0, 1, 0 }); glMatrix.mat4.translate(mvMatrix, new f[] { 5, 0, 0 }); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, cubeVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexNormalBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexNormalAttribute, cubeVertexNormalBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexTextureCoordBuffer); gl.vertexAttribPointer((uint)shaderProgram_textureCoordAttribute, cubeVertexTextureCoordBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, crateTexture); gl.uniform1i(shaderProgram_samplerUniform, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); setMatrixUniforms(); gl.drawElements(gl.TRIANGLES, cubeVertexIndexBuffer_numItems, gl.UNSIGNED_SHORT, 0); mvPopMatrix(); #endregion }; #endregion Native.window.onframe += delegate { if (IsDisposed) return; animate(); drawScene(); }; } ) ); }
public ApplicationContent() { canvas.AttachToDocument(); #region tween NumericEmitter.OfDouble( (value, reserved) => red_obstacle_L_y = (f)value ).With( e => { tween_red_obstacle_L_y = (value) => e(value, 0); } ); NumericEmitter.OfDouble( (value, reserved) => red_obstacle_R_y = (f)value ).With( e => { tween_red_obstacle_R_y = (value) => e(value, 0); } ); NumericEmitter.OfDouble( (value, reserved) => white_arrow_x = (f)value ).With( e => { tween_white_arrow_x = (value) => e(value, 0); } ); NumericEmitter.OfDouble( (value, reserved) => white_arrow_y = (f)value ).With( e => { tween_white_arrow_y = (value) => e(value, 0); } ); #endregion #region canvas Native.document.body.style.overflow = IStyle.OverflowEnum.hidden; #endregion #region gl - Initialise WebGL var gl = new WebGLRenderingContext(); try { gl = (WebGLRenderingContext)canvas.getContext("experimental-webgl"); } catch { } if (gl == null) { Native.window.alert("WebGL not supported"); throw new InvalidOperationException("cannot create webgl context"); } #endregion var gl_viewportWidth = Native.window.Width; var gl_viewportHeight = Native.window.Height; var shaderProgram = 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 #region initShaders var vs = createShader(new GeometryVertexShader()); var fs = createShader(new GeometryFragmentShader()); gl.attachShader(shaderProgram, vs); gl.attachShader(shaderProgram, fs); gl.linkProgram(shaderProgram); gl.useProgram(shaderProgram); var shaderProgram_vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); gl.enableVertexAttribArray((uint)shaderProgram_vertexPositionAttribute); // new in lesson 02 var shaderProgram_vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor"); gl.enableVertexAttribArray((uint)shaderProgram_vertexColorAttribute); var shaderProgram_pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); var shaderProgram_mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); #endregion var mvMatrix = glMatrix.mat4.create(); var mvMatrixStack = new Stack<Float32Array>(); var pMatrix = glMatrix.mat4.create(); #region new in lesson 03 Action mvPushMatrix = delegate { var copy = glMatrix.mat4.create(); glMatrix.mat4.set(mvMatrix, copy); mvMatrixStack.Push(copy); }; Action mvPopMatrix = delegate { mvMatrix = mvMatrixStack.Pop(); }; #endregion #region setMatrixUniforms Action setMatrixUniforms = delegate { gl.uniformMatrix4fv(shaderProgram_pMatrixUniform, false, pMatrix); gl.uniformMatrix4fv(shaderProgram_mvMatrixUniform, false, mvMatrix); }; #endregion var size = 0.03f; #region cube var cubeVertexPositionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); #region vertices var vertices = new[]{ // Front face RED -size, -size, size, size, -size, size, size, size, size, -size, size, size, // Back face YELLOW -size, -size, -size, -size, size, -size, size, size, -size, size, -size, -size, // Top face GREEN -size, size, -size, -size, size, size, size, size, size, size, size, -size, // Bottom face BEIGE -size, -size, -size, size, -size, -size, size, -size, size, -size, -size, size, // Right face PURPLE size, -size, -size, size, size, -size, size, size, size, size, -size, size, // Left face BLUE -size, -size, -size, -size, -size, size, -size, size, size, -size, size, -size }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); #endregion var cubeVertexPositionBuffer_itemSize = 3; var cubeVertexPositionBuffer_numItems = 6 * 6; #region colors_orange var cubeVertexColorBuffer_orange = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer_orange); var colors_orange = new[]{ 1.0f, 0.6f, 0.0f, 1.0f, // Front face 1.0f, 0.6f, 0.0f, 1.0f, // Front face 1.0f, 0.6f, 0.0f, 1.0f, // Front face 1.0f, 0.6f, 0.0f, 1.0f, // Front face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Left face 1.0f, 0.8f, 0.0f, 1.0f, // Left face 1.0f, 0.8f, 0.0f, 1.0f, // Left face 1.0f, 0.8f, 0.0f, 1.0f // Left face }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors_orange), gl.STATIC_DRAW); #endregion #region colors_cyan var cubeVertexColorBuffer_cyan = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer_cyan); var colors_cyan = new[]{ 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors_cyan), gl.STATIC_DRAW); #endregion #region colors_white var cubeVertexColorBuffer_white = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer_white); var colors_white = new[]{ 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors_white), gl.STATIC_DRAW); #endregion #region colors_red var cubeVertexColorBuffer_red = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer_red); var colors_red = new[]{ 1.0f, 0.0f, 0.0f, 1.0f, // Front face 1.0f, 0.0f, 0.0f, 1.0f, // Front face 1.0f, 0.0f, 0.0f, 1.0f, // Front face 1.0f, 0.0f, 0.0f, 1.0f, // Front face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 8.0f, 0.0f, 0.0f, 1.0f, // Top face 8.0f, 0.0f, 0.0f, 1.0f, // Top face 8.0f, 0.0f, 0.0f, 1.0f, // Top face 8.0f, 0.0f, 0.0f, 1.0f, // Top face 8.0f, 0.0f, 0.0f, 1.0f, // Bottom face 8.0f, 0.0f, 0.0f, 1.0f, // Bottom face 8.0f, 0.0f, 0.0f, 1.0f, // Bottom face 8.0f, 0.0f, 0.0f, 1.0f, // Bottom face 9.0f, 0.0f, 0.0f, 1.0f, // Right face 9.0f, 0.0f, 0.0f, 1.0f, // Right face 9.0f, 0.0f, 0.0f, 1.0f, // Right face 9.0f, 0.0f, 0.0f, 1.0f, // Right face 9.0f, 0.0f, 0.0f, 1.0f, // Left face 9.0f, 0.0f, 0.0f, 1.0f, // Left face 9.0f, 0.0f, 0.0f, 1.0f, // Left face 9.0f, 0.0f, 0.0f, 1.0f // Left face }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors_red), gl.STATIC_DRAW); #endregion #region colors_green var cubeVertexColorBuffer_green = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer_green); var colors_green = new[]{ 0.0f, 0.9f, 0.0f, 1.0f, // Front face 0.0f, 0.9f, 0.0f, 1.0f, // Front face 0.0f, 0.9f, 0.0f, 1.0f, // Front face 0.0f, 0.9f, 0.0f, 1.0f, // Front face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.0f, 0.6f, 0.0f, 1.0f, // Top face 0.0f, 0.6f, 0.0f, 1.0f, // Top face 0.0f, 0.6f, 0.0f, 1.0f, // Top face 0.0f, 0.6f, 0.0f, 1.0f, // Top face 0.0f, 0.6f, 0.0f, 1.0f, // Bottom face 0.0f, 0.6f, 0.0f, 1.0f, // Bottom face 0.0f, 0.6f, 0.0f, 1.0f, // Bottom face 0.0f, 0.6f, 0.0f, 1.0f, // Bottom face 0.0f, 0.8f, 0.0f, 1.0f, // Right face 0.0f, 0.8f, 0.0f, 1.0f, // Right face 0.0f, 0.8f, 0.0f, 1.0f, // Right face 0.0f, 0.8f, 0.0f, 1.0f, // Right face 0.0f, 0.8f, 0.0f, 1.0f, // Left face 0.0f, 0.8f, 0.0f, 1.0f, // Left face 0.0f, 0.8f, 0.0f, 1.0f, // Left face 0.0f, 0.8f, 0.0f, 1.0f // Left face }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors_green), gl.STATIC_DRAW); #endregion var cubeVertexColorBuffer_itemSize = 4; var cubeVertexColorBuffer_numItems = 24; var cubeVertexIndexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); var cubeVertexIndices = new UInt16[]{ 0, 1, 2, 0, 2, 3, // Front face 4, 5, 6, 4, 6, 7, // Back face 8, 9, 10, 8, 10, 11, // Top face 12, 13, 14, 12, 14, 15, // Bottom face 16, 17, 18, 16, 18, 19, // Right face 20, 21, 22, 20, 22, 23 // Left face }; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW); var cubeVertexIndexBuffer_itemSize = 1; var cubeVertexIndexBuffer_numItems = cubeVertexPositionBuffer_numItems; #endregion gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); gl.enable(gl.DEPTH_TEST); #region new in lesson 04 var t_start = new IDate().getTime(); var lastTime = 0L; Action animate = delegate { var timeNow = new IDate().getTime(); if (lastTime != 0) { var elapsed = timeNow - lastTime; a -= (75 * elapsed) / 1000.0f; } lastTime = timeNow; t_local = (timeNow - t_start) / 1000; //Native.Document.title = "t: " + t; }; Func<float, float> degToRad = (degrees) => { return degrees * (f)Math.PI / 180f; }; #endregion #region drawScene Action drawScene = delegate { gl.viewport(0, 0, gl_viewportWidth, gl_viewportHeight); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); glMatrix.mat4.perspective(45f, (float)gl_viewportWidth / (float)gl_viewportHeight, 0.1f, 100.0f, pMatrix); glMatrix.mat4.identity(mvMatrix); Action<Action> mw = h => { mvPushMatrix(); h(); mvPopMatrix(); }; #region colors Action red = delegate { gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer_red); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); }; Action green = delegate { gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer_green); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); }; Action orange = delegate { gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer_orange); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); }; Action white = delegate { gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer_white); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); }; Action cyan = delegate { gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer_cyan); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); }; #endregion mw( delegate { glMatrix.mat4.translate(mvMatrix, new[] { 0f, 0.0f, -4f }); glMatrix.mat4.rotate(mvMatrix, degToRad(-70), new[] { 1f, 0f, 0f }); glMatrix.mat4.rotate(mvMatrix, degToRad((f)(Math.Sin(a * 0.0003f) * 33)), new[] { 0f, 0f, 1f }); glMatrix.mat4.translate(mvMatrix, new[] { 0f, camera_z, 0f }); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, cubeVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); // gl.TRIANGLES; var drawElements_mode = gl.TRIANGLES; #region draw Action<f, f, f> draw = (x, y, z) => { mw( delegate { glMatrix.mat4.translate(mvMatrix, new[] { x * size * 2, y * size * 2, z * size * 2 }); setMatrixUniforms(); gl.drawElements(drawElements_mode, cubeVertexIndexBuffer_numItems, gl.UNSIGNED_SHORT, 0); //gl.drawElements(gl.TRIANGLES, cubeVertexIndexBuffer_numItems, gl.UNSIGNED_SHORT, 0); } ); }; #endregion #region at Action<f, f, f, Action> at = (x, y, z, h) => { mw( delegate { glMatrix.mat4.translate(mvMatrix, new[] { x * size * 2, y * size * 2, z * size * 2 }); h(); } ); }; #endregion #region arrow Action arrow = delegate { glMatrix.mat4.translate(mvMatrix, new[] { 0, 0, (float)(Math.Sin(a * 0.1) * size) }); glMatrix.mat4.rotate(mvMatrix, degToRad(a * 0.1f), new[] { 0f, 0f, -1f }); glMatrix.mat4.rotate(mvMatrix, degToRad(a * -0.5f), new[] { 0f, 0f, 1f }); var cc = (cyclecount - cycle) - 1; #region // __X__ if (cc == 0) green(); else white(); draw(0, 0, 0); #endregion #region // _XXX_ if (cc == 1) red(); else white(); draw(-1, 0, 1); draw(1, 0, 1); draw(0, 0, 1); #endregion #region // XXXXX if (cc == 2) orange(); else white(); draw(-2, 0, 2); draw(2, 0, 2); draw(-1, 0, 2); draw(1, 0, 2); draw(0, 0, 2); #endregion #region //XXXXXXX if (cc == 3) orange(); else white(); draw(-3, 0, 3); draw(-2, 0, 3); draw(2, 0, 3); draw(3, 0, 3); draw(-1, 0, 3); draw(1, 0, 3); draw(0, 0, 3); #endregion #region // __X__ if (cc == 4) orange(); else white(); draw(0, 0, 4); #endregion #region // __X__ if (cc == 5) orange(); else white(); draw(0, 0, 5); #endregion #region // __X__ if (cc == 6) orange(); else white(); draw(0, 0, 6); #endregion #region // __X__ if (cc == 7) orange(); else white(); draw(0, 0, 7); #endregion }; #endregion if (white_arrow_y < 8) cyan(); else white(); #region white arrow at(white_arrow_x, white_arrow_y, 1, arrow); #endregion #region draw_obstacle drawElements_mode = gl.LINE_STRIP; white(); white_arrows.WithEach(p => at(p.x, p.y, 1, arrow)); Action draw_obstacle = delegate { draw(-1, 0, 0); draw(-1, 0, 2); draw(0, 0, 1); draw(1, 0, 0); draw(1, 0, 2); }; if (red_obstacle_L_y < 8) red(); else if (red_obstacle_L_y < 16) orange(); else green(); // red at(-10, red_obstacle_L_y, 0, draw_obstacle); at(-6, red_obstacle_L_y, 0, draw_obstacle); at(-2, (red_obstacle_L_y + red_obstacle_L_y + red_obstacle_R_y) / 3, 0, draw_obstacle); if (red_obstacle_R_y < 8) red(); else if (red_obstacle_R_y < 16) orange(); else green(); at(2, (red_obstacle_R_y + red_obstacle_R_y + red_obstacle_L_y) / 3, 0, draw_obstacle); at(6, red_obstacle_R_y, 0, draw_obstacle); at(10, red_obstacle_R_y, 0, draw_obstacle); #endregion drawElements_mode = gl.TRIANGLES; orange(); bool legpart_fill = true; #region leg Action<Action, Action, f, f, f> legpart = (legcolor, fillcolor, x, y, z) => { if (legpart_fill) { drawElements_mode = gl.TRIANGLES; fillcolor(); draw(x, y, z); } drawElements_mode = gl.LINE_STRIP; legcolor(); draw(x, y, z); fillcolor(); drawElements_mode = gl.TRIANGLES; }; Action<Action, Action> leg = (legcolor, fillcolor) => { legpart(legcolor, fillcolor, 0, 6, 0); legpart(legcolor, fillcolor, 0, 5, 1); legpart(legcolor, fillcolor, 0, 4, 2); legpart(legcolor, fillcolor, 0, 3, 2); legpart(legcolor, fillcolor, 0, 2, 1); }; #endregion var sidewaysrange = 20; var verticalrange = 30; f pi = (f)Math.PI; Func<f, f> cos = x => (f)Math.Cos(x); Func<f, f> sin = x => (f)Math.Sin(x); Func<f, f, f> max = (x, y) => (f)Math.Max(x, y); // http://arduino.cc/en/Reference/max #region program_leg0 Action<f, Action<f, f>> program_leg0 = /* void program_leg0 */ (float tphase, notify notify) => { float deg_sideway = (cos(tphase) * sidewaysrange); float deg_vertical = max(0, sin(tphase) * verticalrange); notify(deg_sideway, deg_vertical); } ; #endregion #region program_leg_delay_move_hold_commit Action<int, int, int, Action<f, f>> program_leg_delay_move_hold_commit = /* void program_leg_delay_move_hold_commit */ (int _delay, int hold, int reverse, notify notify) => { float t_accelerated = t * 12; float mod = (pi * (_delay + 1 + hold + 1)); // error: invalid operands of types 'float' and 'float' to binary 'operator%' float phase = (float)((int)(t_accelerated * 100) % (int)(mod * 100)) * 0.01f; // delay if (phase < (pi * _delay)) { if (reverse > 0) phase = pi; else phase = 0; program_leg0(phase, notify); return; } phase -= (pi * _delay); // move if (phase < (pi)) { if (reverse > 0) phase = pi - phase; program_leg0(phase, notify); return; } phase -= (pi); // delay if (phase < (pi * hold)) { if (reverse > 0) phase = 0; else phase = pi; program_leg0(phase, notify); return; } phase -= (pi * hold); if (reverse > 0) phase = pi - phase; // commit program_leg0((pi + phase), notify); } ; #endregion #region program_23_high_five_calibration_far Action program_23_high_five_calibration_far = delegate { leg1up_sideway_deg = sidewaysrange; leg2up_sideway_deg = -sidewaysrange; leg3up_sideway_deg = -sidewaysrange; leg4up_sideway_deg = sidewaysrange; leg1down_vertical_deg = verticalrange; leg2down_vertical_deg = verticalrange; leg3down_vertical_deg = verticalrange; leg4down_vertical_deg = verticalrange; }; #endregion #region program_33_high_five_calibration Action program_33_high_five_calibration = delegate { leg1up_sideway_deg = -sidewaysrange; leg2up_sideway_deg = sidewaysrange; leg3up_sideway_deg = sidewaysrange; leg4up_sideway_deg = -sidewaysrange; leg1down_vertical_deg = verticalrange; leg2down_vertical_deg = verticalrange; leg3down_vertical_deg = verticalrange; leg4down_vertical_deg = verticalrange; }; #endregion #region program_43_high_five_calibration_stand Action program_43_high_five_calibration_stand = delegate { leg1up_sideway_deg = -sidewaysrange; leg2up_sideway_deg = sidewaysrange; leg3up_sideway_deg = sidewaysrange; leg4up_sideway_deg = -sidewaysrange; leg1down_vertical_deg = 0; leg2down_vertical_deg = 0; leg3down_vertical_deg = 0; leg4down_vertical_deg = 0; }; #endregion #region program_53_mayday Action program_53_mayday = delegate { leg1down_vertical_deg = verticalrange; leg2down_vertical_deg = verticalrange; leg3down_vertical_deg = verticalrange; leg4down_vertical_deg = verticalrange; leg1up_sideway_deg = -cos(t * 6) * sidewaysrange; leg2up_sideway_deg = cos(t * 6) * sidewaysrange; leg3up_sideway_deg = cos(t * 6) * sidewaysrange; leg4up_sideway_deg = -cos(t * 6) * sidewaysrange; }; #endregion #region program_13_turn_left Action program_13_turn_left = /* void program_13_turn_left */ () => { program_leg_delay_move_hold_commit(1, 2, 0, (deg_sideway, deg_vertical) => { leg1up_sideway_deg = deg_sideway; leg1down_vertical_deg = deg_vertical; } ); program_leg_delay_move_hold_commit(3, 0, 0, (deg_sideway, deg_vertical) => { leg2up_sideway_deg = deg_sideway; leg2down_vertical_deg = deg_vertical; } ); program_leg_delay_move_hold_commit(2, 1, 0, (deg_sideway, deg_vertical) => { leg3up_sideway_deg = deg_sideway; leg3down_vertical_deg = deg_vertical; } ); program_leg_delay_move_hold_commit(0, 3, 0, (deg_sideway, deg_vertical) => { leg4up_sideway_deg = deg_sideway; leg4down_vertical_deg = deg_vertical; } ); } ; #endregion #region program_14_turn_right Action program_14_turn_right = /* void program_13_turn_left */ () => { program_leg_delay_move_hold_commit(1, 2, 1, (deg_sideway, deg_vertical) => { leg1up_sideway_deg = deg_sideway; leg1down_vertical_deg = deg_vertical; } ); program_leg_delay_move_hold_commit(3, 0, 1, (deg_sideway, deg_vertical) => { leg2up_sideway_deg = deg_sideway; leg2down_vertical_deg = deg_vertical; } ); program_leg_delay_move_hold_commit(2, 1, 1, (deg_sideway, deg_vertical) => { leg3up_sideway_deg = deg_sideway; leg3down_vertical_deg = deg_vertical; } ); program_leg_delay_move_hold_commit(0, 3, 1, (deg_sideway, deg_vertical) => { leg4up_sideway_deg = deg_sideway; leg4down_vertical_deg = deg_vertical; } ); } ; #endregion #region program_15_go_backwards Action program_15_go_backwards = /* void program_13_turn_left */ () => { program_leg_delay_move_hold_commit(1, 2, 0, (deg_sideway, deg_vertical) => { leg1up_sideway_deg = deg_sideway; leg1down_vertical_deg = deg_vertical; } ); program_leg_delay_move_hold_commit(3, 0, 1, (deg_sideway, deg_vertical) => { leg2up_sideway_deg = deg_sideway; leg2down_vertical_deg = deg_vertical; } ); program_leg_delay_move_hold_commit(2, 1, 0, (deg_sideway, deg_vertical) => { leg3up_sideway_deg = deg_sideway; leg3down_vertical_deg = deg_vertical; } ); program_leg_delay_move_hold_commit(0, 3, 1, (deg_sideway, deg_vertical) => { leg4up_sideway_deg = deg_sideway; leg4down_vertical_deg = deg_vertical; } ); } ; #endregion #region program_16_go_forwards Action program_16_go_forwards = /* void program_13_turn_left */ () => { program_leg_delay_move_hold_commit(1, 2, 1, (deg_sideway, deg_vertical) => { leg1up_sideway_deg = deg_sideway; leg1down_vertical_deg = deg_vertical; } ); program_leg_delay_move_hold_commit(3, 0, 0, (deg_sideway, deg_vertical) => { leg2up_sideway_deg = deg_sideway; leg2down_vertical_deg = deg_vertical; } ); program_leg_delay_move_hold_commit(2, 1, 1, (deg_sideway, deg_vertical) => { leg3up_sideway_deg = deg_sideway; leg3down_vertical_deg = deg_vertical; } ); program_leg_delay_move_hold_commit(0, 3, 0, (deg_sideway, deg_vertical) => { leg4up_sideway_deg = deg_sideway; leg4down_vertical_deg = deg_vertical; } ); } ; #endregion #region program_17_go_left Action program_17_go_left = /* void program_17_go_left */ () => { program_leg_delay_move_hold_commit(1, 2, 1, (deg_sideway, deg_vertical) => { leg1up_sideway_deg = deg_sideway; leg1down_vertical_deg = deg_vertical; } ); program_leg_delay_move_hold_commit(3, 0, 1, (deg_sideway, deg_vertical) => { leg2up_sideway_deg = deg_sideway; leg2down_vertical_deg = deg_vertical; } ); program_leg_delay_move_hold_commit(2, 1, 0, (deg_sideway, deg_vertical) => { leg3up_sideway_deg = deg_sideway; leg3down_vertical_deg = deg_vertical; } ); program_leg_delay_move_hold_commit(0, 3, 0, (deg_sideway, deg_vertical) => { leg4up_sideway_deg = deg_sideway; leg4down_vertical_deg = deg_vertical; } ); } ; #endregion #region program_18_go_right Action program_18_go_right = /* void program_18_go_right */ () => { program_leg_delay_move_hold_commit(1, 2, 0, (deg_sideway, deg_vertical) => { leg1up_sideway_deg = deg_sideway; leg1down_vertical_deg = deg_vertical; } ); program_leg_delay_move_hold_commit(3, 0, 0, (deg_sideway, deg_vertical) => { leg2up_sideway_deg = deg_sideway; leg2down_vertical_deg = deg_vertical; } ); program_leg_delay_move_hold_commit(2, 1, 1, (deg_sideway, deg_vertical) => { leg3up_sideway_deg = deg_sideway; leg3down_vertical_deg = deg_vertical; } ); program_leg_delay_move_hold_commit(0, 3, 1, (deg_sideway, deg_vertical) => { leg4up_sideway_deg = deg_sideway; leg4down_vertical_deg = deg_vertical; } ); } ; #endregion //(); if (pp == 23) program_23_high_five_calibration_far(); if (pp == 43) program_43_high_five_calibration_stand(); if (pp == 53) program_53_mayday(); if (pp == 13) program_13_turn_left(); if (pp == 14) program_14_turn_right(); if (pp == 15) program_15_go_backwards(); if (pp == 16) program_16_go_forwards(); if (pp == 17) program_17_go_left(); if (pp == 18) program_18_go_right(); #region legx Action<Action, Action, f, f, f> legx = (wirecolor, fillcolor, x, deg_sideway, deg_vertical) => { mw( delegate { glMatrix.mat4.rotate(mvMatrix, degToRad(x), new[] { 0f, 0f, 1f }); glMatrix.mat4.rotate(mvMatrix, degToRad(deg_sideway), new[] { 0f, 0f, 1f }); glMatrix.mat4.rotate(mvMatrix, degToRad(deg_vertical), new[] { 1f, 0f, 0 }); leg(wirecolor, fillcolor); } ); }; #endregion #region body at(0, 0, 0.5f, delegate { green(); draw(-1, 0, 0); draw(1, 0, 0); orange(); draw(0, -1, 0); draw(0, 1, 0); } ); #endregion #region left front - GREEN - leg2 legx(green, orange, 45, leg2up_sideway_deg, leg2down_vertical_deg); #endregion //legx_y = -2; #region leg right back - BLUE - leg3 legx(cyan, green, 45 + 180, leg3up_sideway_deg, leg3down_vertical_deg); #endregion #region leg left back - WHITE - leg4 legx(white, green, -45 + 180, leg4up_sideway_deg, leg4down_vertical_deg); #endregion #region right front - RED - leg1 legx(red, orange, -45, leg1up_sideway_deg, leg1down_vertical_deg); #endregion } ); }; drawScene(); #endregion #region IsDisposed var IsDisposed = false; Dispose = delegate { if (IsDisposed) return; IsDisposed = true; canvas.Orphanize(); }; #endregion #region AtResize Action AtResize = delegate { canvas.style.SetLocation(0, 0, Native.window.Width, Native.window.Height); gl_viewportWidth = Native.window.Width; gl_viewportHeight = Native.window.Height; canvas.width = Native.window.Width; canvas.height = Native.window.Height; }; AtResize(); Native.window.onresize += delegate { AtResize(); }; #endregion #region onmousewheel Native.Document.body.onmousewheel += e => { camera_z += e.WheelDirection * 0.1f; }; #endregion #region tick var c = 0; Native.window.onframe += delegate { if (IsDisposed) return; c++; //Native.Document.title = "" + c; drawScene(); animate(); if (AtTick != null) AtTick(); }; #endregion #region white_arrows new ScriptCoreLib.JavaScript.Runtime.Timer( delegate { white_arrows.Enqueue( new vec2 { x = white_arrow_x, y = white_arrow_y } ); if (white_arrows.Count > 12) white_arrows.Dequeue(); } ).StartInterval(1000 / 15); #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 }
void InitializeContent(IDefault page = null) { #region make sure we atleast have our invisible DOM if (page == null) page = new HTML.Pages.Default(); #endregion #region container Native.document.body.style.overflow = IStyle.OverflowEnum.hidden; var container = new IHTMLDiv(); container.AttachToDocument(); container.style.backgroundColor = "#000000"; container.style.SetLocation(0, 0, Native.window.Width, Native.window.Height); #endregion #region code port double SCREEN_WIDTH = Native.window.Width ; double SCREEN_HEIGHT = Native.window.Height; var animDelta = 0; var animDeltaDir = -1; var lightVal = 0; var lightDir = 1; var soundVal = 0; var oldSoundVal = 0; var soundDir = 1; #region animate it animDeltaDir *= -1; #endregion var clock = new THREE.Clock(); var morphs = new List<THREE.MorphAnimMesh>(); var updateNoise = true; var mlib = new Dictionary<string, THREE.ShaderMaterial>(); var soundtrack = new Five_Armies { loop = true, volume = 0.9 }; #region HasFocus var HasFocus = false; Native.window.onblur += delegate { HasFocus = false; soundtrack.volume = 0.1; }; Native.window.onfocus += delegate { HasFocus = true; soundtrack.volume = 0.9; }; // Native.Document.onmousemove += //delegate //{ // if (HasFocus) // return; // soundtrack.play(); //}; // Native.Document.onmouseout += // delegate // { // if (HasFocus) // return; // soundtrack.pause(); // }; #endregion var THREE_RepeatWrapping = 0; var THREE_FaceColors = 1; var THREE_LinearFilter = 6; var THREE_RGBFormat = 17; var THREE_LinearMipMapLinearFilter = 8; #region SCENE (RENDER TARGET) var sceneRenderTarget = new THREE.Scene(); var cameraOrtho = new THREE.OrthographicCamera( (int)SCREEN_WIDTH / -2, (int)SCREEN_WIDTH / 2, (int)SCREEN_HEIGHT / 2, (int)SCREEN_HEIGHT / -2, -10000, 10000 ); cameraOrtho.position.z = 100; sceneRenderTarget.add(cameraOrtho); #endregion #region SCENE (FINAL) var scene = new THREE.Scene(); scene.fog = new THREE.Fog(0x050505, 2000, 4000); scene.fog.color.setHSV(0.102, 0.9, 0.825); var camera = new THREE.PerspectiveCamera(40, (int)Native.window.aspect, 2, 4000); camera.position.set(-1200, 800, 1200); scene.add(camera); var controls = new THREE.TrackballControls(camera); controls.target.set(0, 0, 0); controls.rotateSpeed = 1.0; controls.zoomSpeed = 1.2; controls.panSpeed = 0.8; controls.noZoom = false; controls.noPan = false; controls.staticMoving = false; controls.dynamicDampingFactor = 0.15; controls.keys = new[] { 65, 83, 68 }; #endregion #region LIGHTS scene.add(new THREE.AmbientLight(0x111111)); var spotLight = new THREE.SpotLight(0xffffff, 1.15); spotLight.position.set(500, 2000, 0); spotLight.castShadow = true; scene.add(spotLight); var pointLight = new THREE.PointLight(0xff4400, 1.5); pointLight.position.set(0, 0, 0); scene.add(pointLight); #endregion #region HEIGHT + NORMAL MAPS var normalShader = __THREE.ShaderExtras.normalmap; var rx = 256; var ry = 256; var pars = new THREE.WebGLRenderTargetArguments { minFilter = THREE_LinearMipMapLinearFilter, magFilter = THREE_LinearFilter, format = THREE_RGBFormat }; var heightMap = new THREE.WebGLRenderTarget(rx, ry, pars); var normalMap = new THREE.WebGLRenderTarget(rx, ry, pars); var uniformsNoise = new MyUniformsNoise { time = new THREE.ShaderExtrasModuleItem_uniforms_item { type = "f", value = 1.0 }, scale = new THREE.ShaderExtrasModuleItem_uniforms_item { type = "v2", value = new THREE.Vector2(1.5, 1.5) }, offset = new THREE.ShaderExtrasModuleItem_uniforms_item { type = "v2", value = new THREE.Vector2(0, 0) } }; var uniformsNormal = __THREE.UniformsUtils.clone(normalShader.uniforms); uniformsNormal.height.value = 0.05; ((THREE.Vector2)uniformsNormal.resolution.value).set(rx, ry); uniformsNormal.heightMap.texture = heightMap; var vertexShader = new Shaders.NoiseVertexShader().ToString(); #endregion #region before TEXTURES var textureCounter = 0; #region RENDERER var renderer = new THREE.WebGLRenderer(); renderer.setSize(Native.window.Width, Native.window.Height); renderer.setClearColor(scene.fog.color, 1); renderer.domElement.style.position = IStyle.PositionEnum.absolute; renderer.domElement.style.top = "0px"; renderer.domElement.style.left = "0px"; container.appendChild(renderer.domElement); // // renderer.gammaInput = true; renderer.gammaOutput = true; #endregion #region applyShader Action<THREE.ShaderExtrasModuleItem, object, object> applyShader = (shader, texture, target) => { var shaderMaterial = new THREE.ShaderMaterial( new THREE.ShaderMaterialArguments { fragmentShader = shader.fragmentShader, vertexShader = shader.vertexShader, uniforms = __THREE.UniformsUtils.clone(shader.uniforms) } ); shaderMaterial.uniforms.tDiffuse.texture = texture; var sceneTmp = new THREE.Scene(); var meshTmp = new THREE.Mesh(new THREE.PlaneGeometry(Native.window.Width, Native.window.Height), shaderMaterial); meshTmp.position.z = -500; sceneTmp.add(meshTmp); renderer.render(sceneTmp, cameraOrtho, target, true); }; #endregion var terrain = default(THREE.Mesh); #region loadTextures Action loadTextures = () => { textureCounter += 1; if (textureCounter == 3) { terrain.visible = true; //document.getElementById("loading").style.display = "none"; } }; //// #endregion #endregion #region TEXTURES var specularMap = new THREE.WebGLRenderTarget(2048, 2048, pars); var diffuseTexture1 = default(THREE.WebGLRenderTarget); diffuseTexture1 = __THREE.ImageUtils.loadTexture( new global::WebGLDynamicTerrainTemplate.HTML.Images.FromAssets.grasslight_big().src, null, IFunction.Of( delegate () { loadTextures(); applyShader(__THREE.ShaderExtras.luminosity, diffuseTexture1, specularMap); } ) ); var diffuseTexture2 = __THREE.ImageUtils.loadTexture( new global::WebGLDynamicTerrainTemplate.HTML.Images.FromAssets.backgrounddetailed6().src, null, IFunction.Of( delegate () { loadTextures(); } ) ); var detailTexture = __THREE.ImageUtils.loadTexture( new global::WebGLDynamicTerrainTemplate.HTML.Images.FromAssets.grasslight_big_nm().src, null, IFunction.Of( delegate () { loadTextures(); } ) ); diffuseTexture1.wrapS = THREE_RepeatWrapping; diffuseTexture1.wrapT = THREE_RepeatWrapping; diffuseTexture2.wrapS = THREE_RepeatWrapping; diffuseTexture2.wrapT = THREE_RepeatWrapping; detailTexture.wrapS = THREE_RepeatWrapping; detailTexture.wrapT = THREE_RepeatWrapping; specularMap.wrapS = THREE_RepeatWrapping; specularMap.wrapT = THREE_RepeatWrapping; #endregion #region TERRAIN SHADER var terrainShader = __THREE.ShaderTerrain.terrain; var uniformsTerrain = __THREE.UniformsUtils.clone(terrainShader.uniforms); uniformsTerrain.tNormal.texture = normalMap; uniformsTerrain.uNormalScale.value = 3.5; uniformsTerrain.tDisplacement.texture = heightMap; uniformsTerrain.tDiffuse1.texture = diffuseTexture1; uniformsTerrain.tDiffuse2.texture = diffuseTexture2; uniformsTerrain.tSpecular.texture = specularMap; uniformsTerrain.tDetail.texture = detailTexture; uniformsTerrain.enableDiffuse1.value = true; uniformsTerrain.enableDiffuse2.value = true; uniformsTerrain.enableSpecular.value = true; ((THREE.Color)uniformsTerrain.uDiffuseColor.value).setHex(0xffffff); ((THREE.Color)uniformsTerrain.uSpecularColor.value).setHex(0xffffff); ((THREE.Color)uniformsTerrain.uAmbientColor.value).setHex(0x111111); uniformsTerrain.uShininess.value = 30; uniformsTerrain.uDisplacementScale.value = 375; ((THREE.Vector2)uniformsTerrain.uRepeatOverlay.value).set(6, 6); var _params = new[] { new { id= "heightmap", fragmentShader= new Shaders.NoiseFragmentShader().ToString(), vertexShader= vertexShader, uniforms= (object)uniformsNoise, lights = false }, new { id="normal", fragmentShader= normalShader.fragmentShader, vertexShader=normalShader.vertexShader, uniforms=(object)uniformsNormal, lights = false }, new { id="terrain", fragmentShader= terrainShader.fragmentShader, vertexShader=terrainShader.vertexShader, uniforms=(object)uniformsTerrain, lights = true } }; for (var i = 0; i < _params.Length; i++) { var material = new THREE.ShaderMaterial( new THREE.ShaderMaterialArguments { uniforms = (THREE.ShaderExtrasModuleItem_uniforms)_params[i].uniforms, vertexShader = _params[i].vertexShader, fragmentShader = _params[i].fragmentShader, lights = _params[i].lights, fog = true } ); mlib[(string)_params[i].id] = material; } var plane = new THREE.PlaneGeometry(Native.window.Width, Native.window.Height); var quadTarget = new THREE.Mesh( plane, new THREE.MeshBasicMaterial( new THREE.MeshBasicMaterialArguments { color = 0xff0000 } ) ); quadTarget.position.z = -500; sceneRenderTarget.addObject(quadTarget); #endregion #region TERRAIN MESH var geometryTerrain = new THREE.PlaneGeometry(6000, 6000, 256, 256); geometryTerrain.computeFaceNormals(); geometryTerrain.computeVertexNormals(); geometryTerrain.computeTangents(); terrain = new THREE.Mesh(geometryTerrain, mlib["terrain"]); terrain.rotation.set(-Math.PI / 2.0, 0, 0); terrain.position.set(0, -125, 0); terrain.visible = false; scene.add(terrain); #endregion #region COMPOSER renderer.autoClear = false; var renderTargetParameters = new THREE.WebGLRenderTargetArguments { minFilter = THREE_LinearFilter, magFilter = THREE_LinearFilter, format = THREE_RGBFormat, stencilBufer = false }; var renderTarget = new THREE.WebGLRenderTarget((int)SCREEN_WIDTH, (int)SCREEN_HEIGHT, renderTargetParameters); var effectBloom = new THREE.BloomPass(0.6); var effectBleach = new THREE.ShaderPass(__THREE.ShaderExtras.bleachbypass); var hblur = new THREE.ShaderPass(__THREE.ShaderExtras.horizontalTiltShift); var vblur = new THREE.ShaderPass(__THREE.ShaderExtras.verticalTiltShift); var bluriness = 6; hblur.uniforms.h.value = bluriness / SCREEN_WIDTH; vblur.uniforms.v.value = bluriness / SCREEN_HEIGHT; hblur.uniforms.r.value = 0.5; vblur.uniforms.r.value = 0.5; effectBleach.uniforms.opacity.value = 0.65; var composer0 = new THREE.EffectComposer(renderer, renderTarget); var renderModel = new THREE.RenderPass(scene, camera); vblur.renderToScreen = true; var composer = new THREE.EffectComposer(renderer, renderTarget); composer.addPass(renderModel); composer.addPass(effectBloom); //composer.addPass( effectBleach ); composer.addPass(hblur); composer.addPass(vblur); #endregion var r = new Random(); Func<f> Math_random = () => (f)r.NextDouble(); #region addMorph Action<MyModelGeometry, f, f, f, f, f> addMorph = (geometry, speed, duration, x, y, z) => { var material = new THREE.MeshLambertMaterial( new THREE.MeshLambertMaterialArguments { color = 0xffaa55, morphTargets = true, vertexColors = THREE_FaceColors } ); var meshAnim = new THREE.MorphAnimMesh(geometry, material); meshAnim.speed = speed; meshAnim.duration = duration; meshAnim.time = 600.0 * Math_random(); meshAnim.position.set(x, y, z); meshAnim.rotation.y = (f)(Math.PI / 2f); meshAnim.castShadow = true; meshAnim.receiveShadow = false; scene.add(meshAnim); morphs.Add(meshAnim); renderer.initWebGLObjects(scene); }; #endregion #region morphColorsToFaceColors Action<MyModelGeometry> morphColorsToFaceColors = (geometry) => { if (geometry.morphColors != null) if (geometry.morphColors.Length > 0) { var colorMap = geometry.morphColors[0]; for (var i = 0; i < colorMap.colors.Length; i++) { geometry.faces[i].color = colorMap.colors[i]; } } }; #endregion #region Models var loader = new THREE.JSONLoader(); var startX = -3000; loader.load( new Models.parrot().Content.src, IFunction.OfDelegate( new Action<MyModelGeometry>( geometry => { morphColorsToFaceColors(geometry); addMorph(geometry, 250, 500, startX - 500, 500, 700); addMorph(geometry, 250, 500, startX - Math_random() * 500, 500, -200); addMorph(geometry, 250, 500, startX - Math_random() * 500, 500, 200); addMorph(geometry, 250, 500, startX - Math_random() * 500, 500, 1000); } ) ) ); loader.load( new Models.flamingo().Content.src, IFunction.OfDelegate( new Action<MyModelGeometry>( geometry => { morphColorsToFaceColors(geometry); addMorph(geometry, 500, 1000, startX - Math_random() * 500, 350, 40); } ) ) ); loader.load( new Models.stork().Content.src, IFunction.OfDelegate( new Action<MyModelGeometry>( geometry => { morphColorsToFaceColors(geometry); addMorph(geometry, 350, 1000, startX - Math_random() * 500, 350, 340); } ) ) ); #endregion #region PRE-INIT renderer.initWebGLObjects(scene); #endregion #region onkeydown Native.document.body.onkeydown += (e) => { if (e.KeyCode == 78) lightDir *= -1; if (e.KeyCode == 77) animDeltaDir *= -1; if (e.KeyCode == 66) soundDir *= -1; }; #endregion Action __loaded = null; #region event Action loaded; Native.window.parent.With( parent => { __loaded = delegate { __loaded = null; parent.postMessage("WebGLDynamicTerrainTemplate.loaded"); }; } ); #endregion #region render Action render = () => { var delta = clock.getDelta(); soundVal = __THREE.Math.clamp(soundVal + delta * soundDir, 0, 1); if (soundVal != oldSoundVal) { if (soundtrack != null) { soundtrack.volume = soundVal; oldSoundVal = soundVal; } } //Native.Document.title = "textureCounter " + textureCounter; if (terrain.visible) { controls.update(); var Date_now = new IDate().getTime(); var time = Date_now * 0.001; var fLow = 0.4; var fHigh = 0.825; lightVal = __THREE.Math.clamp(lightVal + 0.5 * delta * lightDir, fLow, fHigh); var valNorm = (lightVal - fLow) / (fHigh - fLow); var sat = __THREE.Math.mapLinear(valNorm, 0, 1, 0.95, 0.25); scene.fog.color.setHSV(0.1, sat, lightVal); renderer.setClearColor(scene.fog.color, 1); spotLight.intensity = __THREE.Math.mapLinear(valNorm, 0, 1, 0.1, 1.15); pointLight.intensity = __THREE.Math.mapLinear(valNorm, 0, 1, 0.9, 1.5); uniformsTerrain.uNormalScale.value = __THREE.Math.mapLinear(valNorm, 0, 1, 0.6, 3.5); if (updateNoise) { animDelta = __THREE.Math.clamp(animDelta + 0.00075 * animDeltaDir, 0, 0.05); uniformsNoise.time.value = ((f)uniformsNoise.time.value) + delta * animDelta; var uniformsNoise_offset_value = (THREE.Vector3)uniformsNoise.offset.value; uniformsNoise_offset_value.x += delta * 0.05f; var uniformsTerrain_uOffset_value = (THREE.Vector3)uniformsTerrain.uOffset.value; uniformsTerrain_uOffset_value.x = 4.0f * uniformsNoise_offset_value.x; quadTarget.material = mlib["heightmap"]; renderer.render(sceneRenderTarget, cameraOrtho, heightMap, true); quadTarget.material = mlib["normal"]; renderer.render(sceneRenderTarget, cameraOrtho, normalMap, true); //updateNoise = false; } for (var i = 0; i < morphs.Count; i++) { var morph = morphs[i]; morph.updateAnimation(1000 * delta); morph.position.x += morph.speed * delta; if (morph.position.x > 2000) { morph.position.x = -1500 - Math_random() * 500; } } //renderer.render( scene, camera ); composer.render(0.1); if (__loaded != null) __loaded(); } else { } }; #endregion Native.window.onframe += delegate { if (IsDisposed) return; render(); }; #endregion #region IsDisposed Dispose = delegate { if (IsDisposed) return; IsDisposed = true; //page.song.pause(); soundtrack.pause(); container.Orphanize(); }; #endregion #region AtResize Action AtResize = delegate { container.style.SetLocation(0, 0, Native.window.Width, Native.window.Height); renderer.setSize(Native.window.Width, Native.window.Height); camera.aspect = Native.window.Width / Native.window.Height; camera.updateProjectionMatrix(); }; Native.window.onresize += delegate { AtResize(); }; AtResize(); #endregion Native.document.body.onmousedown += e => { if (e.MouseButton == IEvent.MouseButtonEnum.Middle) { Native.document.body.requestFullscreen(); } }; #region requestFullscreen Native.document.body.ondblclick += delegate { if (IsDisposed) return; // http://tutorialzine.com/2012/02/enhance-your-website-fullscreen-api/ Native.document.body.requestFullscreen(); //AtResize(); }; #endregion }
/// <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) { // works in IE! var size = 500; var gl = new WebGLRenderingContext(); var canvas = gl.canvas.AttachToDocument(); Native.document.body.style.overflow = IStyle.OverflowEnum.hidden; canvas.style.SetLocation(0, 0, size, size); canvas.width = size; canvas.height = size; var gl_viewportWidth = size; var gl_viewportHeight = size; var toolbar = new Toolbar(); if (page != null) { toolbar.Container.AttachToDocument(); toolbar.Container.style.Opacity = 0.7; toolbar.HideButton.onclick += delegate { // ScriptCoreLib.Extensions toolbar.HideTarget.ToggleVisible(); }; } #region IsDisposed var IsDisposed = false; this.Dispose = delegate { if (IsDisposed) return; IsDisposed = true; canvas.Orphanize(); }; #endregion #region AtResize Action AtResize = delegate { gl_viewportWidth = Native.window.Width; gl_viewportHeight = Native.window.Height; canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportHeight); canvas.width = gl_viewportWidth; canvas.height = gl_viewportHeight; }; Native.window.onresize += e => { AtResize(); }; AtResize(); #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 #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 #region programs var programs = new[] { gl.createProgram(new Shaders.PerFragmentLightingVertexShader(), new Shaders.PerFragmentLightingFragmentShader() ) }.Select( shaderProgram => { gl.linkProgram(shaderProgram); var vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); gl.enableVertexAttribArray((uint)vertexPositionAttribute); var vertexNormalAttribute = gl.getAttribLocation(shaderProgram, "aVertexNormal"); gl.enableVertexAttribArray((uint)vertexNormalAttribute); var textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord"); gl.enableVertexAttribArray((uint)textureCoordAttribute); var pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); var mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); var nMatrixUniform = gl.getUniformLocation(shaderProgram, "uNMatrix"); var samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler"); var materialShininessUniform = gl.getUniformLocation(shaderProgram, "uMaterialShininess"); var showSpecularHighlightsUniform = gl.getUniformLocation(shaderProgram, "uShowSpecularHighlights"); var useTexturesUniform = gl.getUniformLocation(shaderProgram, "uUseTextures"); var useLightingUniform = gl.getUniformLocation(shaderProgram, "uUseLighting"); var ambientColorUniform = gl.getUniformLocation(shaderProgram, "uAmbientColor"); var pointLightingLocationUniform = gl.getUniformLocation(shaderProgram, "uPointLightingLocation"); var pointLightingSpecularColorUniform = gl.getUniformLocation(shaderProgram, "uPointLightingSpecularColor"); var pointLightingDiffuseColorUniform = gl.getUniformLocation(shaderProgram, "uPointLightingDiffuseColor"); return new { program = shaderProgram, vertexPositionAttribute, vertexNormalAttribute, textureCoordAttribute, pMatrixUniform, mvMatrixUniform, nMatrixUniform, samplerUniform, materialShininessUniform, showSpecularHighlightsUniform, useTexturesUniform, useLightingUniform, ambientColorUniform, pointLightingLocationUniform, pointLightingSpecularColorUniform, pointLightingDiffuseColorUniform }; } ).ToArray(); #endregion var currentProgram = programs.First(); var mvMatrix = glMatrix.mat4.create(); var mvMatrixStack = new Stack<Float32Array>(); var pMatrix = glMatrix.mat4.create(); #region mvPushMatrix Action mvPushMatrix = delegate { var copy = glMatrix.mat4.create(); glMatrix.mat4.set(mvMatrix, copy); mvMatrixStack.Push(copy); }; #endregion #region mvPopMatrix Action mvPopMatrix = delegate { mvMatrix = mvMatrixStack.Pop(); }; #endregion #region degToRad Func<float, float> degToRad = (degrees) => { return degrees * (f)Math.PI / 180f; }; #endregion // await earth new HTML.Images.FromAssets.earth().InvokeOnComplete( earth => // await metail new HTML.Images.FromAssets.arroway_de_metal_structure_06_d100_flat().InvokeOnComplete( metal => { #region setMatrixUniforms Action setMatrixUniforms = delegate { #region [uniform] mat4 uPMatrix <- pMatrix gl.uniformMatrix4fv(currentProgram.pMatrixUniform, false, pMatrix); #endregion #region [uniform] mat4 uMVMatrix <- mvMatrix gl.uniformMatrix4fv(currentProgram.mvMatrixUniform, false, mvMatrix); #endregion var normalMatrix = glMatrix.mat3.create(); glMatrix.mat4.toInverseMat3(mvMatrix, normalMatrix); glMatrix.mat3.transpose(normalMatrix); #region [uniform] mat3 uNMatrix <- normalMatrix gl.uniformMatrix3fv(currentProgram.nMatrixUniform, false, normalMatrix); #endregion }; #endregion #region handleLoadedTexture Action<WebGLTexture, IHTMLImage> handleLoadedTexture = (texture, texture_image) => { gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1); gl.bindTexture(gl.TEXTURE_2D, texture); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture_image); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, (int)gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, (int)gl.LINEAR_MIPMAP_NEAREST); gl.generateMipmap(gl.TEXTURE_2D); gl.bindTexture(gl.TEXTURE_2D, null); }; #endregion var earthTexture = gl.createTexture(); handleLoadedTexture(earthTexture, earth); var galvanizedTexture = gl.createTexture(); handleLoadedTexture(galvanizedTexture, metal); new WebGLLesson14.Data.Teapot().Content.AttachToDocument().onload += delegate { #region loadTeapot var teapotData = Application.Teapot; var teapotVertexNormalBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, teapotVertexNormalBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(teapotData.vertexNormals), gl.STATIC_DRAW); var teapotVertexNormalBuffer_itemSize = 3; var teapotVertexNormalBuffer_numItems = teapotData.vertexNormals.Length / 3; var teapotVertexTextureCoordBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, teapotVertexTextureCoordBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(teapotData.vertexTextureCoords), gl.STATIC_DRAW); var teapotVertexTextureCoordBuffer_itemSize = 2; var teapotVertexTextureCoordBuffer_numItems = teapotData.vertexTextureCoords.Length / 2; var teapotVertexPositionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, teapotVertexPositionBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(teapotData.vertexPositions), gl.STATIC_DRAW); var teapotVertexPositionBuffer_itemSize = 3; var teapotVertexPositionBuffer_numItems = teapotData.vertexPositions.Length / 3; var teapotVertexIndexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, teapotVertexIndexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(teapotData.indices), gl.STATIC_DRAW); var teapotVertexIndexBuffer_itemSize = 1; var teapotVertexIndexBuffer_numItems = teapotData.indices.Length; #endregion gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); gl.enable(gl.DEPTH_TEST); var teapotAngle = 180f; var lastTime = 0L; #region animate Action animate = () => { var timeNow = new IDate().getTime(); if (lastTime != 0) { var elapsed = timeNow - lastTime; teapotAngle += 0.05f * elapsed; } lastTime = timeNow; }; #endregion //Func<string, f> parseFloat = Convert.ToSingle; Func<string, f> parseFloat = x => float.Parse(x); #region drawScene Action drawScene = () => { gl.useProgram(currentProgram.program); gl.viewport(0, 0, gl_viewportWidth, gl_viewportHeight); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); //if (teapotVertexPositionBuffer == null || teapotVertexNormalBuffer == null || teapotVertexTextureCoordBuffer == null || teapotVertexIndexBuffer == null) { // return; //} glMatrix.mat4.perspective(45, gl_viewportWidth / gl_viewportHeight, 0.1f, 100.0f, pMatrix); var shaderProgram = currentProgram; var specularHighlights = toolbar.specular.@checked; #region [uniform] bool uShowSpecularHighlights <- toolbar.specular.@checked gl.uniform1i(shaderProgram.showSpecularHighlightsUniform, Convert.ToInt32(specularHighlights)); #endregion var lighting = toolbar.lighting.@checked; #region [uniform] bool uUseLighting <- toolbar.lighting.@checked gl.uniform1i(shaderProgram.useLightingUniform, Convert.ToInt32(lighting)); #endregion if (lighting) { #region [uniform] uAmbientColor <- ambientR, ambientG, ambientB gl.uniform3f( shaderProgram.ambientColorUniform, parseFloat(toolbar.ambientR.value), parseFloat(toolbar.ambientG.value), parseFloat(toolbar.ambientB.value) ); #endregion #region [uniform] uPointLightingLocation <- lightPositionX, lightPositionY, lightPositionZ gl.uniform3f( shaderProgram.pointLightingLocationUniform, parseFloat(toolbar.lightPositionX.value), parseFloat(toolbar.lightPositionY.value), parseFloat(toolbar.lightPositionZ.value) ); #endregion #region [uniform] uPointLightingSpecularColor <- specularR, specularG, specularB gl.uniform3f( shaderProgram.pointLightingSpecularColorUniform, parseFloat(toolbar.specularR.value), parseFloat(toolbar.specularG.value), parseFloat(toolbar.specularB.value) ); #endregion #region [uniform] uPointLightingDiffuseColor <- diffuseR, diffuseG, diffuseB gl.uniform3f( shaderProgram.pointLightingDiffuseColorUniform, parseFloat(toolbar.diffuseR.value), parseFloat(toolbar.diffuseG.value), parseFloat(toolbar.diffuseB.value) ); #endregion } var texture = toolbar.texture[toolbar.texture.selectedIndex].value; gl.uniform1i(shaderProgram.useTexturesUniform, Convert.ToInt32(texture != "none")); glMatrix.mat4.identity(mvMatrix); glMatrix.mat4.translate(mvMatrix, new f[] { 0, 0, -40 }); glMatrix.mat4.rotate(mvMatrix, degToRad(23.4f), new f[] { 1, 0, -1 }); glMatrix.mat4.rotate(mvMatrix, degToRad(teapotAngle), new f[] { 0, 1, 0 }); gl.activeTexture(gl.TEXTURE0); if (texture == "earth") { gl.bindTexture(gl.TEXTURE_2D, earthTexture); } else if (texture == "galvanized") { gl.bindTexture(gl.TEXTURE_2D, galvanizedTexture); } gl.uniform1i(shaderProgram.samplerUniform, 0); gl.uniform1f(shaderProgram.materialShininessUniform, parseFloat(toolbar.shininess.value)); gl.bindBuffer(gl.ARRAY_BUFFER, teapotVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram.vertexPositionAttribute, teapotVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, teapotVertexTextureCoordBuffer); gl.vertexAttribPointer((uint)shaderProgram.textureCoordAttribute, teapotVertexTextureCoordBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, teapotVertexNormalBuffer); gl.vertexAttribPointer((uint)shaderProgram.vertexNormalAttribute, teapotVertexNormalBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, teapotVertexIndexBuffer); setMatrixUniforms(); gl.drawElements(gl.TRIANGLES, teapotVertexIndexBuffer_numItems, gl.UNSIGNED_SHORT, 0); }; #endregion Native.window.onframe += delegate { if (IsDisposed) return; animate(); drawScene(); }; }; } ) ); }
/// <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 size = 500; var gl = new WebGLRenderingContext(); var canvas = gl.canvas.AttachToDocument(); Native.document.body.style.overflow = IStyle.OverflowEnum.hidden; canvas.style.SetLocation(0, 0, size, size); canvas.width = size; canvas.height = size; var gl_viewportWidth = size; var gl_viewportHeight = size; #region IsDisposed var IsDisposed = false; this.Dispose = delegate { if (IsDisposed) return; IsDisposed = true; canvas.Orphanize(); }; #endregion #region AtResize Action AtResize = delegate { gl_viewportWidth = Native.window.Width; gl_viewportHeight = Native.window.Height; canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportHeight); canvas.width = gl_viewportWidth; canvas.height = gl_viewportHeight; }; Native.window.onresize += e => { AtResize(); }; AtResize(); #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 #region initShaders var shaderProgram = gl.createProgram( new GeometryVertexShader(), new GeometryFragmentShader() ); gl.linkProgram(shaderProgram); gl.useProgram(shaderProgram); var shaderProgram_vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); gl.enableVertexAttribArray((uint)shaderProgram_vertexPositionAttribute); // new in lesson 02 var shaderProgram_vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor"); gl.enableVertexAttribArray((uint)shaderProgram_vertexColorAttribute); var shaderProgram_pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); var shaderProgram_mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); #endregion var mvMatrix = glMatrix.mat4.create(); var mvMatrixStack = new Stack<Float32Array>(); var pMatrix = glMatrix.mat4.create(); #region new in lesson 03 Action mvPushMatrix = delegate { var copy = glMatrix.mat4.create(); glMatrix.mat4.set(mvMatrix, copy); mvMatrixStack.Push(copy); }; Action mvPopMatrix = delegate { mvMatrix = mvMatrixStack.Pop(); }; #endregion #region setMatrixUniforms Action setMatrixUniforms = delegate { gl.uniformMatrix4fv(shaderProgram_pMatrixUniform, false, pMatrix); gl.uniformMatrix4fv(shaderProgram_mvMatrixUniform, false, mvMatrix); }; #endregion #region init buffers #region pyramid var pyramidVertexPositionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, pyramidVertexPositionBuffer); var vertices = new[]{ // Front face 0.0f, 1.0f, 0.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, // Right face 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, // Back face 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, // Left face 0.0f, 1.0f, 0.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); var pyramidVertexPositionBuffer_itemSize = 3; var pyramidVertexPositionBuffer_numItems = 12; var pyramidVertexColorBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, pyramidVertexColorBuffer); var colors = new[]{ // Front face 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // Right face 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, // Back face 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // Left face 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW); var pyramidVertexColorBuffer_itemSize = 4; var pyramidVertexColorBuffer_numItems = 12; #endregion #region cube var cubeVertexPositionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); vertices = new[]{ // Front face RED -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, // Back face YELLOW -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, // Top face GREEN -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, // Bottom face BEIGE -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, // Right face PURPLE 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, // Left face BLUE -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); var cubeVertexPositionBuffer_itemSize = 3; var cubeVertexPositionBuffer_numItems = 6 * 6; var cubeVertexColorBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer); colors = new[]{ // RED 1.0f, 0.0f, 0.0f, 1.0f, // Front face 1.0f, 0.0f, 0.0f, 1.0f, // Front face 1.0f, 0.0f, 0.0f, 1.0f, // Front face 1.0f, 0.0f, 0.0f, 1.0f, // Front face // YELLOW 1.0f, 1.0f, 0.0f, 1.0f, // Back face 1.0f, 1.0f, 0.0f, 1.0f, // Back face 1.0f, 1.0f, 0.0f, 1.0f, // Back face 1.0f, 1.0f, 0.0f, 1.0f, // Back face // GREEN 0.0f, 1.0f, 0.0f, 1.0f, // Top face 0.0f, 1.0f, 0.0f, 1.0f, // Top face 0.0f, 1.0f, 0.0f, 1.0f, // Top face 0.0f, 1.0f, 0.0f, 1.0f, // Top face 1.0f, 0.5f, 0.5f, 1.0f, // Bottom face 1.0f, 0.5f, 0.5f, 1.0f, // Bottom face 1.0f, 0.5f, 0.5f, 1.0f, // Bottom face 1.0f, 0.5f, 0.5f, 1.0f, // Bottom face 1.0f, 0.0f, 1.0f, 1.0f, // Right face 1.0f, 0.0f, 1.0f, 1.0f, // Right face 1.0f, 0.0f, 1.0f, 1.0f, // Right face 1.0f, 0.0f, 1.0f, 1.0f, // Right face 0.0f, 0.0f, 1.0f, 1.0f, // Left face 0.0f, 0.0f, 1.0f, 1.0f, // Left face 0.0f, 0.0f, 1.0f, 1.0f, // Left face 0.0f, 0.0f, 1.0f, 1.0f // Left face }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW); var cubeVertexColorBuffer_itemSize = 4; var cubeVertexColorBuffer_numItems = 24; var cubeVertexIndexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); var cubeVertexIndices = new UInt16[]{ 0, 1, 2, 0, 2, 3, // Front face 4, 5, 6, 4, 6, 7, // Back face 8, 9, 10, 8, 10, 11, // Top face 12, 13, 14, 12, 14, 15, // Bottom face 16, 17, 18, 16, 18, 19, // Right face 20, 21, 22, 20, 22, 23 // Left face }; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW); var cubeVertexIndexBuffer_itemSize = 1; var cubeVertexIndexBuffer_numItems = cubeVertexPositionBuffer_numItems; #endregion #endregion gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); gl.enable(gl.DEPTH_TEST); #region new in lesson 04 var rPyramid = 0f; var rCube = 0f; var lastTime = 0L; Action animate = delegate { var timeNow = new IDate().getTime(); if (lastTime != 0) { var elapsed = timeNow - lastTime; rPyramid += (90 * elapsed) / 1000.0f; rCube -= (75 * elapsed) / 1000.0f; } lastTime = timeNow; }; Func<float, float> degToRad = (degrees) => { return degrees * (f)Math.PI / 180f; }; #endregion #region drawScene Action drawScene = delegate { gl.viewport(0, 0, gl_viewportWidth, gl_viewportHeight); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); glMatrix.mat4.perspective(45f, (float)gl_viewportWidth / (float)gl_viewportHeight, 0.1f, 100.0f, pMatrix); glMatrix.mat4.identity(mvMatrix); glMatrix.mat4.translate(mvMatrix, new float[] { -1.5f, 0.0f, -7.0f }); #region new in lesson 03 mvPushMatrix(); // we�re changing our current rotation state as stored in the model-view matrix // MVC? :) glMatrix.mat4.rotate(mvMatrix, degToRad(rPyramid), new float[] { 0f, 1f, 0f }); #endregion gl.bindBuffer(gl.ARRAY_BUFFER, pyramidVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, pyramidVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, pyramidVertexColorBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, pyramidVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); setMatrixUniforms(); gl.drawArrays(gl.TRIANGLES, 0, pyramidVertexPositionBuffer_numItems); #region new in lesson 03 mvPopMatrix(); #endregion glMatrix.mat4.translate(mvMatrix, new float[] { 3.0f, 0.0f, 0.0f }); #region new in lesson 04 mvPushMatrix(); glMatrix.mat4.rotate(mvMatrix, degToRad(rCube), new float[] { 1f, 1f, 1f }); #endregion gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, cubeVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); setMatrixUniforms(); gl.drawElements(gl.TRIANGLES, cubeVertexIndexBuffer_numItems, gl.UNSIGNED_SHORT, 0); #region new in lesson 03 mvPopMatrix(); #endregion }; drawScene(); #endregion var c = 0; Native.window.onframe += delegate { c++; Native.document.title = "" + c; drawScene(); animate(); }; //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.style.color = "yellow"; // dragme.AllowToDragAsApplicationPackage(); // } //); }
// https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150719/chromeudpwindwheel /// <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(IApp page) { #region += Launched chrome.app.window dynamic self = Native.self; dynamic self_chrome = self.chrome; object self_chrome_socket = self_chrome.socket; if (self_chrome_socket != null) { if (!(Native.window.opener == null && Native.window.parent == Native.window.self)) { Console.WriteLine("chrome.app.window.create, is that you?"); // pass thru } else { // should jsc send a copresence udp message? chrome.runtime.UpdateAvailable += delegate { new chrome.Notification(title: "UpdateAvailable"); }; chrome.app.runtime.Launched += async delegate { // 0:12094ms chrome.app.window.create {{ href = chrome-extension://aemlnmcokphbneegoefdckonejmknohh/_generated_background_page.html }} Console.WriteLine("chrome.app.window.create " + new { Native.document.location.href }); new chrome.Notification(title: "ChromeUDPSendAsync"); // https://developer.chrome.com/apps/app_window#type-CreateWindowOptions var xappwindow = await chrome.app.window.create( Native.document.location.pathname, options: new { alwaysOnTop = true, visibleOnAllWorkspaces = true } ); //xappwindow.setAlwaysOnTop xappwindow.show(); await xappwindow.contentWindow.async.onload; Console.WriteLine("chrome.app.window loaded!"); }; return; } } #endregion // X:\jsc.svn\examples\javascript\WorkerMD5Experiment\WorkerMD5Experiment\Application.cs // "C:\Users\Arvo\AppData\Local\Google\Chrome SxS\Application\chrome.exe - es3.lnk" var size = 600; var gl = new WebGLRenderingContext(); var canvas = gl.canvas.AttachToDocument(); Native.document.body.style.overflow = IStyle.OverflowEnum.hidden; canvas.style.SetLocation(0, 0, size, size); canvas.width = size; canvas.height = size; var gl_viewportWidth = size; var gl_viewportHeight = size; // can AssetLibrary create a special type // and define the variables // for it we need to parse glsl? // if we dont parse the code yet, // do we parse the macros and fields neogh already to do that? // Geometry var shaderProgram = gl.createProgram( new WebGLWindWheel.Shaders.GeometryVertexShader(), new WebGLWindWheel.Shaders.GeometryFragmentShader() ); gl.linkProgram(shaderProgram); gl.useProgram(shaderProgram); var shaderProgram_vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); gl.enableVertexAttribArray((uint)shaderProgram_vertexPositionAttribute); // new in lesson 02 var shaderProgram_vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor"); gl.enableVertexAttribArray((uint)shaderProgram_vertexColorAttribute); var shaderProgram_pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); var shaderProgram_mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); // https://hacks.mozilla.org/2014/10/introducing-simd-js/ // https://github.com/toji/gl-matrix/blob/master/src/gl-matrix/mat4.js // http://www.i-programmer.info/news/167-javascript/8578-chrome-to-support-simdjs.html // https://code.google.com/p/v8/issues/detail?id=2228 //var SIMD_mat4 = new System.Numerics.Matrix4x4(); //var SIMD_mat4s = new Stack<System.Numerics.Matrix4x4>(); // can we convert this code to NDK friendly non GC library? // for gearVR 90FOV and cardboard wearality 150FOV #region __mat4 var __mat4 = new { // X:\jsc.svn\examples\javascript\Test\TestFloatArray\TestFloatArray\Application.cs // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2015/20150706/20150708 // generic in the sens of caller choosing is the return type a new struct or out ref? perspective = new Func<float[], float, float, float, float, float[]>( (that, fovy, aspect, near, far) => { var f = 1.0f / (float)Math.Tan(fovy / 2f); var nf = 1f / (near - far); that[0] = f / aspect; that[1] = 0; that[2] = 0; that[3] = 0; that[4] = 0; that[5] = f; that[6] = 0; that[7] = 0; that[8] = 0; that[9] = 0; that[10] = (far + near) * nf; that[11] = -1; that[12] = 0; that[13] = 0; that[14] = (2 * far * near) * nf; that[15] = 0; return that; }), // reset content of mat4 identity = new Func<float[], float[]>( that => { //Array.Copy() //var xx =&that; var xx = new float[] { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, }; //is this the best way to update array contents? xx.CopyTo(that, 0); return xx; } ), create = new Func<float[]>( () => //new mat4() new float[] { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, } ), #region not used? clone = new Func<float[], float[]>( smat4 => //new mat4() new float[] { smat4[0], smat4[1], smat4[2], smat4[3], smat4[4], smat4[5], smat4[6], smat4[7], smat4[8], smat4[9], smat4[10], smat4[11], smat4[12], smat4[13], smat4[14], smat4[15], } ) #endregion , // X:\jsc.svn\examples\java\android\vr\OVRWindWheelNDK\OVRWindWheelNDK\References\VrApi.ovrMatrix4f.cs translate = new Func<float[], float[], float[], float[]>( (float[] that, float[] output, float[] xyz) => { float xx = xyz[0], y = xyz[1], z = xyz[2]; if (output == that) { that[12] = output[0] * xx + output[4] * y + output[8] * z + output[12]; that[13] = output[1] * xx + output[5] * y + output[9] * z + output[13]; that[14] = output[2] * xx + output[6] * y + output[10] * z + output[14]; that[15] = output[3] * xx + output[7] * y + output[11] * z + output[15]; return that; } float a00, a01, a02, a03, a10, a11, a12, a13, a20, a21, a22, a23; a00 = output[0]; a01 = output[1]; a02 = output[2]; a03 = output[3]; a10 = output[4]; a11 = output[5]; a12 = output[6]; a13 = output[7]; a20 = output[8]; a21 = output[9]; a22 = output[10]; a23 = output[11]; that[0] = a00; that[1] = a01; that[2] = a02; that[3] = a03; that[4] = a10; that[5] = a11; that[6] = a12; that[7] = a13; that[8] = a20; that[9] = a21; that[10] = a22; that[11] = a23; that[12] = a00 * xx + a10 * y + a20 * z + output[12]; that[13] = a01 * xx + a11 * y + a21 * z + output[13]; that[14] = a02 * xx + a12 * y + a22 * z + output[14]; that[15] = a03 * xx + a13 * y + a23 * z + output[15]; return that; } ), rotate = new Func<float[], float[], float, float[], float[]>( (that, a, rad, axis) => { float x = axis[0], y = axis[1], z = axis[2]; float len = (float)Math.Sqrt(x * x + y * y + z * z), s, c, t, a00, a01, a02, a03, a10, a11, a12, a13, a20, a21, a22, a23, b00, b01, b02, b10, b11, b12, b20, b21, b22; if (Math.Abs(len) < float.Epsilon) return that; len = 1f / len; x *= len; y *= len; z *= len; s = (float)Math.Sin(rad); c = (float)Math.Cos(rad); t = 1 - c; a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3]; a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7]; a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11]; // Construct the elements of the rotation matrix b00 = x * x * t + c; b01 = y * x * t + z * s; b02 = z * x * t - y * s; b10 = x * y * t - z * s; b11 = y * y * t + c; b12 = z * y * t + x * s; b20 = x * z * t + y * s; b21 = y * z * t - x * s; b22 = z * z * t + c; // Perform rotation-specific matrix multiplication that[0] = a00 * b00 + a10 * b01 + a20 * b02; that[1] = a01 * b00 + a11 * b01 + a21 * b02; that[2] = a02 * b00 + a12 * b01 + a22 * b02; that[3] = a03 * b00 + a13 * b01 + a23 * b02; that[4] = a00 * b10 + a10 * b11 + a20 * b12; that[5] = a01 * b10 + a11 * b11 + a21 * b12; that[6] = a02 * b10 + a12 * b11 + a22 * b12; that[7] = a03 * b10 + a13 * b11 + a23 * b12; that[8] = a00 * b20 + a10 * b21 + a20 * b22; that[9] = a01 * b20 + a11 * b21 + a21 * b22; that[10] = a02 * b20 + a12 * b21 + a22 * b22; that[11] = a03 * b20 + a13 * b21 + a23 * b22; if (a != that) { // If the source and destination differ, copy the unchanged last row that[12] = a[12]; that[13] = a[13]; that[14] = a[14]; that[15] = a[15]; } return that; } ) }; #endregion // set to identity var mvMatrix = __mat4.create(); var mvMatrixStack = new Stack<float[]>(); // set to perspective var pMatrix = __mat4.create(); #region new in lesson 03 // how would this translate to non GC, NDK? Action mvPushMatrix = delegate { var copy = __mat4.create(); mvMatrix.CopyTo(copy, 0); //glMatrix.mat4.set(mvMatrix, copy); mvMatrixStack.Push(copy); }; Action mvPopMatrix = delegate { mvMatrix = mvMatrixStack.Pop(); }; #endregion #region setMatrixUniforms Action setMatrixUniforms = delegate { gl.uniformMatrix4fv(shaderProgram_pMatrixUniform, false, pMatrix); gl.uniformMatrix4fv(shaderProgram_mvMatrixUniform, false, mvMatrix); }; #endregion #region init buffers #region cube var cubeVertexPositionBuffer = new WebGLBuffer(gl); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); //var cubesize = 1.0f * 0.05f; //var cubesize = 1.0f * 0.1f; var cubesize = 16 / 128f; //var cubesize = 1.0f; var vertices = new[]{ // Front face -cubesize, -cubesize, cubesize, cubesize, -cubesize, cubesize, cubesize, cubesize, cubesize, -cubesize, cubesize, cubesize, // Back face -cubesize, -cubesize, -cubesize, -cubesize, cubesize, -cubesize, cubesize, cubesize, -cubesize, cubesize, -cubesize, -cubesize, // Top face -cubesize, cubesize, -cubesize, -cubesize, cubesize, cubesize, cubesize, cubesize, cubesize, cubesize, cubesize, -cubesize, // Bottom face -cubesize, -cubesize, -cubesize, cubesize, -cubesize, -cubesize, cubesize, -cubesize, cubesize, -cubesize, -cubesize, cubesize, // Right face cubesize, -cubesize, -cubesize, cubesize, cubesize, -cubesize, cubesize, cubesize, cubesize, cubesize, -cubesize, cubesize, // Left face -cubesize, -cubesize, -cubesize, -cubesize, -cubesize, cubesize, -cubesize, cubesize, cubesize, -cubesize, cubesize, -cubesize }; gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); var cubeVertexPositionBuffer_itemSize = 3; var cubeVertexPositionBuffer_numItems = 6 * 6; var squareVertexColorBuffer = new WebGLBuffer(gl); gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexColorBuffer); // 216, 191, 18 var colors = new[]{ 1.0f, 0.6f, 0.0f, 1.0f, // Front face 1.0f, 0.6f, 0.0f, 1.0f, // Front face 1.0f, 0.6f, 0.0f, 1.0f, // Front face 1.0f, 0.6f, 0.0f, 1.0f, // Front face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Left face 1.0f, 0.8f, 0.0f, 1.0f, // Left face 1.0f, 0.8f, 0.0f, 1.0f, // Left face 1.0f, 0.8f, 0.0f, 1.0f // Left face }; gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW); var cubeVertexColorBuffer_itemSize = 4; var cubeVertexColorBuffer_numItems = 24; // ELEMENT_ARRAY_BUFFER : WebGLBuffer? // drawElements var cubeVertexIndexBuffer = new WebGLBuffer(gl); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); //var cubeVertexIndices = new UInt16[]{ var cubeVertexIndices = new byte[]{ 0, 1, 2, 0, 2, 3, // Front face 4, 5, 6, 4, 6, 7, // Back face 8, 9, 10, 8, 10, 11, // Top face 12, 13, 14, 12, 14, 15, // Bottom face 16, 17, 18, 16, 18, 19, // Right face 20, 21, 22, 20, 22, 23 // Left face }; // ushort[]? //gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndices, gl.STATIC_DRAW); var cubeVertexIndexBuffer_itemSize = 1; var cubeVertexIndexBuffer_numItems = 36; #endregion #endregion gl.clearColor(0.0f, 0.0f, 0.0f, alpha: 1.0f); gl.enable(gl.DEPTH_TEST); var rWindDelta = 0.1f; var rCubeDelta = 1.0f; var rCube = 0f; var rWind = 0f; var lastTime = 0L; Action animate = delegate { var timeNow = new IDate().getTime(); if (lastTime != 0) { var elapsed = timeNow - lastTime; rCube -= ((75 * elapsed) / 1000.0f) * rCubeDelta; rWind -= ((75 * elapsed) / 1000.0f) * rWindDelta; } lastTime = timeNow; }; #region degToRad Func<float, float> degToRad = (degrees) => { return degrees * (float)Math.PI / 180f; }; #endregion #region AtResize Action AtResize = delegate { gl_viewportWidth = Native.window.Width; gl_viewportHeight = Native.window.Height; canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportHeight); canvas.width = gl_viewportWidth; canvas.height = gl_viewportHeight; }; Native.window.onresize += e => { AtResize(); }; AtResize(); #endregion #region ui to vr var keys_ad = 0; var keys_ws = 0; var keys_c = 0; var mousebutton = 0; var mousewheel = 0; var mx = 0; var my = 0; #endregion canvas.tabIndex = 1; #region onkeydown canvas.onkeydown += async e => { var A = e.KeyCode == 65; var D = e.KeyCode == 68; if (A || D) { keys_ad = e.KeyCode; //Native.document.title = new { e.CursorX, e.CursorY }.ToString(); //wasd.innerText = new { e.KeyCode, ad = keys_ad, ws = keys_ws }.ToString(); while ((await canvas.async.onkeyup).KeyCode != e.KeyCode) ; //var ee = await div.async.onkeyup; keys_ad = 0; //wasd.innerText = new { e.KeyCode, ad = keys_ad, ws = keys_ws }.ToString(); return; } // CS // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150704 if (e.KeyCode == 67) { keys_c = e.KeyCode; //Native.document.title = new { e.CursorX, e.CursorY }.ToString(); //wasd.innerText = new { e.KeyCode, keys_ad, keys_ws, keys_c }.ToString(); while ((await canvas.async.onkeyup).KeyCode != e.KeyCode) ; //var ee = await div.async.onkeyup; keys_c = 0; //wasd.innerText = new { e.KeyCode, keys_ad, keys_ws, keys_c }.ToString(); return; } { keys_ws = e.KeyCode; //Native.document.title = new { e.CursorX, e.CursorY }.ToString(); //wasd.innerText = new { e.KeyCode, ad = keys_ad, ws = keys_ws }.ToString(); while ((await canvas.async.onkeyup).KeyCode != e.KeyCode) ; //var ee = await div.async.onkeyup; keys_ws = 0; //wasd.innerText = new { e.KeyCode, ad = keys_ad, ws = keys_ws }.ToString(); } }; #endregion #region onmousemove canvas.onmousewheel += e => { // since we are a chrome app. is chrome sending us wheel delta too? mousewheel += e.WheelDirection; }; canvas.onmousemove += e => { // we could tilt the svg cursor // like we do on heat zeeker:D mx += e.movementX; my += e.movementY; //Native.document.title = new { e.CursorX, e.CursorY }.ToString(); //xy.innerText = new { x, y }.ToString(); }; canvas.onmousedown += async e => { // wont work for RemoteApp users tho mousebutton = (int)e.MouseButton; // await ? canvas.requestPointerLock(); //e.CaptureMouse(); var ee = await canvas.async.onmouseup; //var ee = await div.async.ondblclick; if (ee.MouseButton == IEvent.MouseButtonEnum.Right) Native.document.exitPointerLock(); mousebutton = 0; }; #endregion var vertexTransform = new float[0]; new { }.With( async delegate { var n = await chrome.socket.getNetworkList(); var n24 = n.Where(nn => nn.prefixLength == 24).ToArray(); n24.WithEach( async nic => { var port = new Random().Next(16000, 40000); var socket = new UdpClient(); socket.Client.Bind( //new IPEndPoint(IPAddress.Any, port: 40000) new IPEndPoint(IPAddress.Parse(nic.address), port) ); // this will eat too much memory? //div.ownerDocument.defaultView.onframe += canvas.onframe += delegate { // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150704 var nmessage = mx + ":" + my + ":" + keys_ad + ":" + keys_ws + ":" + keys_c + ":" + mousebutton + ":" + mousewheel; var data = Encoding.UTF8.GetBytes(nmessage); //creates a variable b of type byte //new IHTMLPre { "about to send... " + new { data.Length } }.AttachToDocument(); // X:\jsc.svn\examples\javascript\chrome\apps\ChromeUDPNotification\ChromeUDPNotification\Application.cs socket.Send( data, data.Length, hostname: "239.1.2.3", port: 41814 ); }; var uu = new UdpClient(40014); uu.JoinMulticastGroup(IPAddress.Parse("239.1.2.3")); while (true) { var xx = await uu.ReceiveAsync(); // did we jump to ui thread? // https://www.khronos.org/registry/typedarray/specs/latest/ vertexTransform = new Float32Array(new Uint8ClampedArray(xx.Buffer).buffer); } } ); } ); var sw = Stopwatch.StartNew(); Native.window.onframe += e => { gl.viewport(0, 0, gl_viewportWidth, gl_viewportHeight); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); #region pMatrix __mat4.perspective( pMatrix, 90f, (float)gl_viewportWidth / (float)gl_viewportHeight, 0.1f, 100.0f ); //__mat4.rotate(pMatrix, pMatrix, (float)Math.PI + mx * 0.005f, new float[] { 0, 1f, 0f }); __mat4.rotate(pMatrix, pMatrix, mx * 0.005f, new float[] { 0, 1f, 0f }); #endregion //var cubesize = 1.0f * 0.05f; if (vertexTransform.Length == 0) { __mat4.identity(mvMatrix); __mat4.translate(mvMatrix, mvMatrix, new float[] { -1.5f, 0.0f, -3.0f }); #region windwheel mvPushMatrix(); __mat4.rotate(mvMatrix, mvMatrix, degToRad(rWind), new float[] { 0, 1f, 0f }); #region DrawFrameworkWingAtX Action<float, float> DrawFrameworkWingAtX = (WingX, WingY) => { mvPushMatrix(); __mat4.translate(mvMatrix, mvMatrix, new float[] { cubesize * WingX, cubesize * WingY, 0 }); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, cubeVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexColorBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); setMatrixUniforms(); gl.drawElements(gl.TRIANGLES, cubeVertexPositionBuffer_numItems, gl.UNSIGNED_BYTE, 0); mvPopMatrix(); }; #endregion #region DrawWingAtX Action<int, int, float, float> DrawWingAtX = (WingX, WingSize, WingRotationMultiplier, WingRotationOffset) => { mvPushMatrix(); __mat4.translate(mvMatrix, mvMatrix, new float[] { cubesize * WingX, 0, 0 }); if (WingRotationOffset == 0) { DrawFrameworkWingAtX(0, 0); } #region DrawWingPart Action<float> DrawWingPart = PartIndex => { mvPushMatrix(); __mat4.rotate(mvMatrix, mvMatrix, degToRad(WingRotationOffset + (rCube * WingRotationMultiplier)), new float[] { 1f, 0f, 0f }); __mat4.translate(mvMatrix, mvMatrix, new float[] { 0f, cubesize * PartIndex * 2, 0 }); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, cubeVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexColorBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); setMatrixUniforms(); gl.drawElements(gl.TRIANGLES, cubeVertexPositionBuffer_numItems, gl.UNSIGNED_BYTE, 0); mvPopMatrix(); }; #endregion #region DrawWingWithSize Action<int> DrawWingWithSize = length => { for (int i = 4; i < length; i++) { DrawWingPart(i * 1.0f); DrawWingPart(-i * 1.0f); } }; #endregion DrawWingWithSize(WingSize); mvPopMatrix(); }; #endregion var x = 8; DrawFrameworkWingAtX(x - 8, 0); for (int i = 0; i < 24; i++) { DrawFrameworkWingAtX(x - 8, -2.0f * i); } DrawWingAtX(x - 6, 0, 1f, 0); DrawWingAtX(x - 4, 0, 1f, 0); DrawWingAtX(x - 2, 0, 1f, 0); DrawWingAtX(x + 0, 16, 1f, 0); DrawWingAtX(x + 0, 16, 1f, 30); DrawWingAtX(x + 0, 16, 1f, 60); DrawWingAtX(x + 0, 16, 1f, 90); DrawWingAtX(x + 0, 16, 1f, 120); DrawWingAtX(x + 0, 16, 1f, 150); DrawWingAtX(x + 2, 0, 1f, 0); DrawWingAtX(x + 4, 0, 1f, 0); DrawWingAtX(x + 6, 0, 1f, 0); DrawWingAtX(x + 8, 12, 0.4f, 0); DrawWingAtX(x + 8, 12, 0.4f, 60); DrawWingAtX(x + 8, 12, 0.4f, 120); DrawWingAtX(x + 8 + 2, 0, 1f, 0); DrawWingAtX(x + 8 + 4, 0, 1f, 0); DrawWingAtX(x + 8 + 6, 0, 1f, 0); DrawWingAtX(x + 16, 8, 0.3f, 0); DrawWingAtX(x + 16, 8, 0.3f, 90); mvPopMatrix(); #endregion } #region draw cube on the right to remind where we started //glMatrix.mat4.translate(mvMatrix, new float[] { 3.0f, 2.0f, 0.0f }); // how do we scale it? //mvMatrix = __mat4.create(); //mvMatrix = new float[] //{ // 1, 0, 0, 0, // 0, 1, 0, 0, // 0, 0, 1, 0, // 0, 0, 0, 1, //}; //f = new Float32Array( [1, 0, 0, 1.5, 0, 1, 0, 2, 0, 0, 1, -3, 0, 0, 0, 1]); //a[0].__mat4.identity.WRMABg6gjTWKCO_aNXgMMAA(a[0].mvMatrix); //a[0].__mat4.translate.YRMABiCCKT_aaNWnR3f4qdg(a[0].mvMatrix, a[0].mvMatrix, new Float32Array( [1.5, 2, -3])); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, cubeVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexColorBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); gl.uniformMatrix4fv(shaderProgram_pMatrixUniform, false, pMatrix); // https://www.physicsforums.com/threads/what-is-the-purpose-of-the-transpose.261849/ var mvMatrix0transpose = new float[] { 9, 0, 0,0, 0, 4, 0, 0, 0, 0, 4, 0, 1.5f, 2.0f, -9.0f, 1, }; // X:\jsc.svn\examples\javascript\chrome\apps\ChromeUDPFloats\ChromeUDPFloats\Application.cs var ElementCount = vertexTransform.Length / (64 / 4); for (int ElementIndex = 0; ElementIndex < ElementCount; ElementIndex++) { var mvMatrix0 = new float[16]; for (int j = 0; j < 16; j++) { var ff = vertexTransform[j + ElementIndex * 64 / 4]; //Console.WriteLine(new { j, ff }); mvMatrix0[j] = ff; } mvMatrix0transpose = new[] { mvMatrix0[0], mvMatrix0[4], mvMatrix0[8],mvMatrix0[12], mvMatrix0[1],mvMatrix0[5],mvMatrix0[9],mvMatrix0[13], mvMatrix0[2],mvMatrix0[6],mvMatrix0[10],mvMatrix0[14], mvMatrix0[3],mvMatrix0[7],mvMatrix0[11],mvMatrix0[15] }; gl.uniformMatrix4fv(shaderProgram_mvMatrixUniform, false, mvMatrix0transpose); gl.drawElements(gl.TRIANGLES, cubeVertexPositionBuffer_numItems, gl.UNSIGNED_BYTE, 0); } #endregion animate(); }; }
/// <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 size = 500; var gl = new WebGLRenderingContext(); var canvas = gl.canvas.AttachToDocument(); Native.document.body.style.overflow = IStyle.OverflowEnum.hidden; canvas.style.SetLocation(0, 0, size, size); canvas.width = size; canvas.height = size; var gl_viewportWidth = size; var gl_viewportHeight = size; #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 #region init shaders var shaderProgram = gl.createProgram( new Shaders.GeometryVertexShader(), new Shaders.GeometryFragmentShader() ); gl.linkProgram(shaderProgram); gl.useProgram(shaderProgram); #region getAttribLocation Func<string, long> getAttribLocation = name => gl.getAttribLocation(shaderProgram, name); #endregion var shaderProgram_vertexPositionAttribute = getAttribLocation("aVertexPosition"); gl.enableVertexAttribArray((uint)shaderProgram_vertexPositionAttribute); var shaderProgram_textureCoordAttribute = getAttribLocation("aTextureCoord"); gl.enableVertexAttribArray((uint)shaderProgram_textureCoordAttribute); #region getUniformLocation Func<string, WebGLUniformLocation> getUniformLocation = name => gl.getUniformLocation(shaderProgram, name); #endregion var shaderProgram_pMatrixUniform = getUniformLocation("uPMatrix"); var shaderProgram_mvMatrixUniform = getUniformLocation("uMVMatrix"); var shaderProgram_samplerUniform = getUniformLocation("uSampler"); var shaderProgram_colorUniform = getUniformLocation("uColor"); #endregion var mvMatrix = glMatrix.mat4.create(); var mvMatrixStack = new Stack<Float32Array>(); var pMatrix = glMatrix.mat4.create(); #region mvPushMatrix Action mvPushMatrix = delegate { var copy = glMatrix.mat4.create(); glMatrix.mat4.set(mvMatrix, copy); mvMatrixStack.Push(copy); }; #endregion #region mvPopMatrix Action mvPopMatrix = delegate { mvMatrix = mvMatrixStack.Pop(); }; #endregion #region setMatrixUniforms Action setMatrixUniforms = delegate { gl.uniformMatrix4fv(shaderProgram_pMatrixUniform, false, pMatrix); gl.uniformMatrix4fv(shaderProgram_mvMatrixUniform, false, mvMatrix); }; #endregion #region degToRad Func<float, float> degToRad = (degrees) => { return degrees * (f)Math.PI / 180f; }; #endregion #region currentlyPressedKeys var currentlyPressedKeys = new Dictionary<int, bool> { {33, false}, {34, false}, {37, false}, {39, false}, {38, false}, {40, false} }; Native.Document.onkeydown += e => { currentlyPressedKeys[e.KeyCode] = true; }; Native.Document.onkeyup += e => { currentlyPressedKeys[e.KeyCode] = false; }; #endregion var zoom = -15f; var tilt = 90f; var spin = 0f; #region handleKeys Action handleKeys = delegate { if (currentlyPressedKeys[33]) { // Page Up zoom -= 0.1f; } if (currentlyPressedKeys[34]) { // Page Down zoom += 0.1f; } if (currentlyPressedKeys[38]) { // Up cursor key tilt += 2; } if (currentlyPressedKeys[40]) { // Down cursor key tilt -= 2; } }; #endregion #region initBuffers var starVertexPositionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, starVertexPositionBuffer); var vertices = new f[]{ -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); var starVertexPositionBuffer_itemSize = 3; var starVertexPositionBuffer_numItems = 4; var starVertexTextureCoordBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, starVertexTextureCoordBuffer); var textureCoords = new f[]{ 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoords), gl.STATIC_DRAW); var starVertexTextureCoordBuffer_itemSize = 2; var starVertexTextureCoordBuffer_numItems = 4; #endregion #region initWorldObjects var stars = new List<Star>(); var numStars = 50f; for (var i = 0; i < numStars; i++) { stars.Add(new Star((i / numStars) * 5.0f, i / numStars)); } #endregion #region animate var lastTime = 0L; Action animate = () => { var timeNow = new IDate().getTime(); if (lastTime != 0) { var elapsed = timeNow - lastTime; foreach (var star in stars) { star.animate(elapsed); } } lastTime = timeNow; }; #endregion gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); #region AtResize Action AtResize = delegate { gl_viewportWidth = Native.window.Width; gl_viewportHeight = Native.window.Height; 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 HTML.Images.FromAssets.star().InvokeOnComplete( texture_image => { var starTexture = gl.createTexture(); #region handleLoadedTexture gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1); gl.bindTexture(gl.TEXTURE_2D, starTexture); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture_image); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, (int)gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, (int)gl.LINEAR); gl.bindTexture(gl.TEXTURE_2D, null); #endregion #region drawStar Action drawStar = () => { gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, starTexture); gl.uniform1i(shaderProgram_samplerUniform, 0); gl.bindBuffer(gl.ARRAY_BUFFER, starVertexTextureCoordBuffer); gl.vertexAttribPointer((uint)shaderProgram_textureCoordAttribute, starVertexTextureCoordBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, starVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, starVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); setMatrixUniforms(); gl.drawArrays(gl.TRIANGLE_STRIP, 0, starVertexPositionBuffer_numItems); }; #endregion #region drawScene Action drawScene = delegate { gl.viewport(0, 0, gl_viewportWidth, gl_viewportHeight); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); glMatrix.mat4.perspective(45, gl_viewportWidth / gl_viewportHeight, 0.1f, 100.0f, pMatrix); gl.blendFunc(gl.SRC_ALPHA, gl.ONE); gl.enable(gl.BLEND); glMatrix.mat4.identity(mvMatrix); glMatrix.mat4.translate(mvMatrix, new f[] {0.0f, 0.0f, zoom}); glMatrix.mat4.rotate(mvMatrix, degToRad(tilt),new f[] { 1.0f, 0.0f, 0.0f}); //var twinkle = document.getElementById("twinkle").checked; var twinkle = false; foreach (var star in stars) { star.draw( tilt, spin, twinkle, mvPushMatrix, mvPopMatrix, mvMatrix, drawStar, shaderProgram_colorUniform, gl ); spin += 0.1f; } }; #endregion Native.window.onframe += delegate { if (IsDisposed) return; handleKeys(); drawScene(); animate(); }; } ); }
public File(string name=null, string fullPath=null, string type=null, IDate lastModifiedDate=null, int size=0) { }
public __DateTime(int year, int month, int day, int hours, int minutes, int seconds) { InternalValue = new IDate(); InternalValue.setFullYear(year); InternalValue.setMonth(month - 1); InternalValue.setDate(day); InternalValue.setHours(hours); InternalValue.setMinutes(minutes); InternalValue.setSeconds(seconds); }
public Application(IDefault page = null) { var size = 500; var gl = new WebGLRenderingContext(antialias: true, preserveDrawingBuffer: true); this.canvas = gl.canvas.AttachToDocument(); canvas.style.backgroundColor = "black"; //canvas.style.backgroundColor = "blue"; Native.document.body.style.overflow = IStyle.OverflowEnum.hidden; canvas.style.SetLocation(0, 0, size, size); canvas.width = size; canvas.height = size; var gl_viewportWidth = size; var gl_viewportHeight = size; canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportHeight); #region IsDisposed var IsDisposed = false; this.Dispose = delegate { if (IsDisposed) return; IsDisposed = true; canvas.Orphanize(); }; #endregion #region AtResize Action AtResize = delegate { gl_viewportWidth = Native.window.Width; gl_viewportHeight = Native.window.Height; canvas.style.SetSize(gl_viewportWidth, gl_viewportHeight); canvas.width = gl_viewportWidth; canvas.height = gl_viewportHeight; }; if (page != null) Native.window.onresize += e => { AtResize(); }; AtResize(); #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 #region initShaders var shaderProgram = gl.createProgram( new GeometryVertexShader(), new GeometryFragmentShader() ); gl.linkProgram(shaderProgram); gl.useProgram(shaderProgram); var shaderProgram_vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); gl.enableVertexAttribArray((uint)shaderProgram_vertexPositionAttribute); var shaderProgram_textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord"); gl.enableVertexAttribArray((uint)shaderProgram_textureCoordAttribute); var shaderProgram_pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); var shaderProgram_mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); // new in lesson 05 var shaderProgram_samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler"); #endregion var mvMatrix = glMatrix.mat4.create(); var mvMatrixStack = new Stack<Float32Array>(); var pMatrix = glMatrix.mat4.create(); #region new in lesson 03 Action mvPushMatrix = delegate { var copy = glMatrix.mat4.create(); glMatrix.mat4.set(mvMatrix, copy); mvMatrixStack.Push(copy); }; Action mvPopMatrix = delegate { mvMatrix = mvMatrixStack.Pop(); }; #endregion #region setMatrixUniforms Action setMatrixUniforms = delegate { gl.uniformMatrix4fv(shaderProgram_pMatrixUniform, false, pMatrix); gl.uniformMatrix4fv(shaderProgram_mvMatrixUniform, false, mvMatrix); }; #endregion #region init buffers #region cubeVertexPositionBuffer var cubeVertexPositionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); var vertices = new[]{ // Front face RED -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, //// Back face YELLOW //-1.0f, -1.0f, -1.0f, //-1.0f, 1.0f, -1.0f, // 1.0f, 1.0f, -1.0f, // 1.0f, -1.0f, -1.0f, //// Top face GREEN //-1.0f, 1.0f, -1.0f, //-1.0f, 1.0f, 1.0f, // 1.0f, 1.0f, 1.0f, // 1.0f, 1.0f, -1.0f, //// Bottom face BEIGE //-1.0f, -1.0f, -1.0f, // 1.0f, -1.0f, -1.0f, // 1.0f, -1.0f, 1.0f, //-1.0f, -1.0f, 1.0f, //// Right face PURPLE // 1.0f, -1.0f, -1.0f, // 1.0f, 1.0f, -1.0f, // 1.0f, 1.0f, 1.0f, // 1.0f, -1.0f, 1.0f, //// Left face //-1.0f, -1.0f, -1.0f, //-1.0f, -1.0f, 1.0f, //-1.0f, 1.0f, 1.0f, //-1.0f, 1.0f, -1.0f }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); var cubeVertexPositionBuffer_itemSize = 3; //var cubeVertexPositionBuffer_numItems = 6 * 6; var cubeVertexPositionBuffer_numItems = 6 * 1; #endregion #region cubeVertexTextureCoordBuffer var cubeVertexTextureCoordBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexTextureCoordBuffer); var textureCoords = new float[]{ // Front face 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, //// Back face //1.0f, 0.0f, //1.0f, 1.0f, //0.0f, 1.0f, //0.0f, 0.0f, //// Top face //0.0f, 1.0f, //0.0f, 0.0f, //1.0f, 0.0f, //1.0f, 1.0f, //// Bottom face //1.0f, 1.0f, //0.0f, 1.0f, //0.0f, 0.0f, //1.0f, 0.0f, //// Right face //1.0f, 0.0f, //1.0f, 1.0f, //0.0f, 1.0f, //0.0f, 0.0f, //// Left face //0.0f, 0.0f, //1.0f, 0.0f, //1.0f, 1.0f, //0.0f, 1.0f, }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoords), gl.STATIC_DRAW); var cubeVertexTextureCoordBuffer_itemSize = 2; var cubeVertexTextureCoordBuffer_numItems = 24; var cubeVertexIndexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); var cubeVertexIndices = new UInt16[]{ 0, 1, 2, 0, 2, 3, // Front face 4, 5, 6, 4, 6, 7, // Back face 8, 9, 10, 8, 10, 11, // Top face 12, 13, 14, 12, 14, 15, // Bottom face 16, 17, 18, 16, 18, 19, // Right face 20, 21, 22, 20, 22, 23 // Left face }; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW); var cubeVertexIndexBuffer_itemSize = 1; var cubeVertexIndexBuffer_numItems = cubeVertexPositionBuffer_numItems; #endregion #endregion var tex1 = gl.createTexture(); var tex1i = new WebGLSVGAnonymous.HTML.Images.FromAssets.Anonymous_LogosSingleNoWings(); //var tex1i = new WebGLSVGAnonymous.HTML.Images.FromAssets.nehe(); // WebGL: drawElements: texture bound to texture unit 0 is not renderable. It maybe non-power-of-2 and have incompatible texture filtering or is not 'texture complete'. Or the texture is Float or Half Float type with linear filtering while OES_float_linear or OES_half_float_linear extension is not enabled. tex1i.width = 1024 * 2; tex1i.height = 1024 * 2; // initTexture new in lesson 05 var tex0 = gl.createTexture(); var tex0i = new WebGLSVGAnonymous.HTML.Images.FromAssets.Anonymous_LogosSingleWings(); //var tex0i = new WebGLSVGAnonymous.HTML.Images.FromAssets.nehe(); // WebGL: drawElements: texture bound to texture unit 0 is not renderable. It maybe non-power-of-2 and have incompatible texture filtering or is not 'texture complete'. Or the texture is Float or Half Float type with linear filtering while OES_float_linear or OES_half_float_linear extension is not enabled. tex0i.width = 1024 * 2; tex0i.height = 1024 * 2; tex1i.InvokeOnComplete( delegate { tex0i.InvokeOnComplete( delegate { // this is a workaround // chrome has a bug where svg textures are merged.. var tex1ii = new CanvasRenderingContext2D(1024 * 2, 1024 * 2); tex1ii.drawImage( tex1i, 0, 0, 1024 * 2, 1024 * 2); { gl.activeTexture(gl.TEXTURE1); gl.bindTexture(gl.TEXTURE_2D, tex1); gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, tex1ii.canvas); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, (int)gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, (int)gl.NEAREST); gl.generateMipmap(gl.TEXTURE_2D); gl.bindTexture(gl.TEXTURE_2D, null); } { gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, tex0); gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1); // http://msdn.microsoft.com/en-us/library/ie/dn302435(v=vs.85).aspx gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, tex0i); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, (int)gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, (int)gl.NEAREST); gl.generateMipmap(gl.TEXTURE_2D); gl.bindTexture(gl.TEXTURE_2D, null); } //gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); //gl.enable(gl.DEPTH_TEST); gl.enable(gl.BLEND); //gl.enable(gl.CULL_FACE); // http://stackoverflow.com/questions/11521035/blending-with-html-background-in-webgl gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA); var xRot = 0.0f; var yRot = 0.0f; var zRot = 0.0f; var lastTime = 0L; Action animate = delegate { var timeNow = new IDate().getTime(); if (lastTime != 0) { var elapsed = timeNow - lastTime; //xRot += (9 * elapsed) / 1000.0f; yRot += (40 * elapsed) / 1000.0f; //zRot += (9 * elapsed) / 1000.0f; } lastTime = timeNow; }; Func<float, float> degToRad = (degrees) => { return degrees * (f)Math.PI / 180f; }; var f = new Designer(); f.trackBar1.Value = -20; f.trackBar2.Value = -10; if (page != null) f.Show(); Action<bool> drawScene = Anonymous_LogosSingleNoWings_Checked => { glMatrix.mat4.perspective(45f, (float)gl_viewportWidth / (float)gl_viewportHeight, 0.1f, 100.0f, pMatrix); glMatrix.mat4.identity(mvMatrix); var u1 = f.trackBar1.Value * 0.1f; glMatrix.mat4.translate(mvMatrix, new float[] { 0.0f, 0.0f, u1 }); //glMatrix.mat4.rotate(mvMatrix, degToRad(xRot), new[] { 1f, 0f, 0f }); if (Anonymous_LogosSingleNoWings_Checked) glMatrix.mat4.rotate(mvMatrix, degToRad(yRot), new[] { 0f, 1f, 0f }); else glMatrix.mat4.rotate(mvMatrix, degToRad(f.trackBar3.Value), new[] { 0f, 1f, 0f }); var u2 = f.trackBar2.Value * 0.1f; glMatrix.mat4.translate(mvMatrix, new float[] { 0.0f, 0.0f, u2 }); Native.document.title = new { u1, u2 }.ToString(); //glMatrix.mat4.rotate(mvMatrix, degToRad(zRot), new[] { 0f, 0f, 1f }); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, cubeVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexTextureCoordBuffer); gl.vertexAttribPointer((uint)shaderProgram_textureCoordAttribute, cubeVertexTextureCoordBuffer_itemSize, gl.FLOAT, false, 0, 0); if (Anonymous_LogosSingleNoWings_Checked) { gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, tex0); gl.uniform1i(shaderProgram_samplerUniform, 0); } else { gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, tex1); gl.uniform1i(shaderProgram_samplerUniform, 0); } gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); setMatrixUniforms(); gl.drawElements(gl.TRIANGLES, cubeVertexIndexBuffer_numItems, gl.UNSIGNED_SHORT, 0); gl.bindTexture(gl.TEXTURE_2D, null); }; var c = 0; Native.window.onframe += delegate { c++; if (page == null) { gl_viewportWidth = canvas.clientWidth; gl_viewportHeight = canvas.clientHeight; canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportHeight); canvas.width = gl_viewportWidth; canvas.height = gl_viewportHeight; } gl.viewport(0, 0, gl_viewportWidth, gl_viewportHeight); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); if (f.Anonymous_LogosSingleNoWings.Checked) drawScene(false); if (f.Anonymous_LogosSingleWings.Checked) drawScene(true); animate(); }; } ); } ); }
void InitializeContent(IDefault page = null) { var gl_viewportWidth = 800; var gl_viewportHeight = 640; #region canvas var canvas = new IHTMLCanvas().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 #region gl - Initialise WebGL var gl = default(gl); try { gl = (gl)canvas.getContext("experimental-webgl"); } catch { } if (gl == null) { Native.window.alert("WebGL not supported"); throw new InvalidOperationException("cannot create webgl context"); } #endregion #region Dispose var IsDisposed = false; Dispose = delegate { if (IsDisposed) return; IsDisposed = true; canvas.Orphanize(); }; #endregion #region initShaders var shaderProgram = gl.createProgram( new GeometryVertexShader(), new GeometryFragmentShader() ); gl.linkProgram(shaderProgram); gl.useProgram(shaderProgram); var vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); gl.enableVertexAttribArray((uint)vertexPositionAttribute); var vertexNormalAttribute = gl.getAttribLocation(shaderProgram, "aVertexNormal"); gl.enableVertexAttribArray((uint)vertexNormalAttribute); var vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor"); gl.enableVertexAttribArray((uint)vertexColorAttribute); #endregion gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); gl.clearDepth(1.0f); gl.enable(gl.DEPTH_TEST); // missing from WebGL IDL? //gl.enable(gl.POLYGON_SMOOTH); // Enable point size gl.enable(0x8642); gl.depthFunc(gl.LEQUAL); #region initBuffers var vertexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); var planet = new Planet(129); var planetData = planet.generate(); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(planetData.vertices), gl.STATIC_DRAW); var vertexBuffer_itemSize = 3; var vertexBuffer_numItems = planetData.vertices.Length / 3; var colorBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(planetData.colors), gl.STATIC_DRAW); var colorBuffer_itemSize = 4; var colorBuffer_numItems = planetData.colors.Length / 4; var normalBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(planetData.normals), gl.STATIC_DRAW); var normalBuffer_itemSize = 3; var normalBuffer_numItems = planetData.normals.Length / 3; var indexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(planetData.indices), gl.STATIC_DRAW); var indexBuffer_itemSize = 1; var indexBuffer_numItems = planetData.indices.Length; #endregion var lastTime = 0L; var yRot = -180.0f; var ySpeed = -50.0f; #region glCore var mvMatrix = default(Matrix); var mvMatrixStack = new Stack<Matrix>(); var pMatrix = default(Matrix); Action loadIdentity = delegate { mvMatrix = __sylvester.Matrix.I(4); }; Action<float, float, float, float> perspective = (fovy, aspect, znear, zfar) => { pMatrix = __glUtils.globals.makePerspective(fovy, aspect, znear, zfar); }; Action<Matrix> multMatrix = (m) => { mvMatrix = mvMatrix.x(m); }; // http://prototypejs.org/api/array/flatten Action setMatrixUniforms = delegate { var shaderProgram_pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); gl.uniformMatrix4fv(shaderProgram_pMatrixUniform, false, new Float32Array(pMatrix.flatten())); var shaderProgram_mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); gl.uniformMatrix4fv(shaderProgram_mvMatrixUniform, false, new Float32Array(mvMatrix.flatten())); var normalMatrix = mvMatrix.inverse(); normalMatrix = normalMatrix.transpose(); var nUniform = gl.getUniformLocation(shaderProgram, "uNMatrix"); gl.uniformMatrix4fv(nUniform, false, new Float32Array(mvMatrix.flatten())); }; Action<float, float[]> mvRotate = (ang, v) => { var arad = ang * Math.PI / 180.0; var m = __sylvester.Matrix.Rotation(arad, __sylvester.Vector.create(new[] { v[0], v[1], v[2] })).ensure4x4(); multMatrix(m); }; Action<f, f, f, f, f, f, f, f, f> lookAt = (ex, ey, ez, cx, cy, cz, ux, uy, uz) => { mvMatrix = mvMatrix.x(__glUtils.globals.makeLookAt(ex, ey, ez, cx, cy, cz, ux, uy, uz)); }; #endregion #region drawScene Action drawScene = delegate { gl.viewport(0, 0, gl_viewportWidth, gl_viewportHeight); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); //perspective(45f, (float)gl_viewportWidth / (float)gl_viewportHeight, 0.1f, 100.0f); perspective(60f, (float)gl_viewportWidth / (float)gl_viewportHeight, 0.1f, 1000.0f); //perspective(60f, 800 / 640, 0.1f, 1000.0f); loadIdentity(); lookAt(0, 0, 500, 0, 0, 0, 0, 1, 0); mvRotate(yRot, new[] { 0f, 1f, 0f }); gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); gl.vertexAttribPointer((uint)vertexPositionAttribute, vertexBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer); gl.vertexAttribPointer((uint)vertexNormalAttribute, normalBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); gl.vertexAttribPointer((uint)vertexColorAttribute, colorBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); setMatrixUniforms(); gl.drawElements(gl.TRIANGLES, indexBuffer_numItems, gl.UNSIGNED_SHORT, 0); //gl.drawArrays(gl.POINTS, 0, vertexBuffer.numItems); }; #endregion #region animate Action animate = () => { var timeNow = new IDate().getTime(); if (lastTime != 0) { var elapsed = timeNow - lastTime; yRot += (ySpeed * elapsed) / 1000.0f; } lastTime = timeNow; }; #endregion #region tick Action tick = null; tick = () => { drawScene(); animate(); Native.window.requestAnimationFrame += tick; }; Native.window.requestAnimationFrame += tick; #endregion #region AtResize Action AtResize = delegate { gl_viewportWidth = Native.window.Width; gl_viewportHeight = Native.window.Height; canvas.style.SetLocation(0, 0, Native.window.Width, Native.window.Height); canvas.width = Native.window.Width; canvas.height = Native.window.Height; }; #region onresize Native.window.onresize += delegate { AtResize(); }; #endregion AtResize(); #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 }
/// <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 size = 500; var gl = new WebGLRenderingContext(); var canvas = gl.canvas.AttachToDocument(); Native.document.body.style.overflow = IStyle.OverflowEnum.hidden; canvas.style.SetLocation(0, 0, size, size); canvas.width = size; canvas.height = size; var gl_viewportWidth = size; var gl_viewportHeight = size; #region IsDisposed var IsDisposed = false; this.Dispose = delegate { if (IsDisposed) return; IsDisposed = true; canvas.Orphanize(); }; #endregion #region AtResize Action AtResize = delegate { gl_viewportWidth = Native.window.Width; gl_viewportHeight = Native.window.Height; canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportHeight); canvas.width = gl_viewportWidth; canvas.height = gl_viewportHeight; }; Native.window.onresize += e => { AtResize(); }; AtResize(); #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 toolbar = new Toolbar(); if (page != null) { toolbar.Container.style.Opacity = 0.7; toolbar.Container.AttachToDocument(); toolbar.HideButton.onclick += delegate { // ScriptCoreLib.Extensions toolbar.HideTarget.ToggleVisible(); }; } #region initShaders var shaderProgram = gl.createProgram( new GeometryVertexShader(), new GeometryFragmentShader() ); gl.linkProgram(shaderProgram); gl.useProgram(shaderProgram); #region getAttribLocation Func<string, long> getAttribLocation = name => gl.getAttribLocation(shaderProgram, name); var shaderProgram_vertexPositionAttribute = getAttribLocation("aVertexPosition"); gl.enableVertexAttribArray((uint)shaderProgram_vertexPositionAttribute); var shaderProgram_vertexNormalAttribute = getAttribLocation("aVertexNormal"); gl.enableVertexAttribArray((uint)shaderProgram_vertexNormalAttribute); var shaderProgram_textureCoordAttribute = getAttribLocation("aTextureCoord"); gl.enableVertexAttribArray((uint)shaderProgram_textureCoordAttribute); #endregion #region getUniformLocation Func<string, WebGLUniformLocation> getUniformLocation = name => gl.getUniformLocation(shaderProgram, name); var shaderProgram_pMatrixUniform = getUniformLocation("uPMatrix"); var shaderProgram_mvMatrixUniform = getUniformLocation("uMVMatrix"); var shaderProgram_nMatrixUniform = getUniformLocation("uNMatrix"); var shaderProgram_samplerUniform = getUniformLocation("uSampler"); var shaderProgram_useLightingUniform = getUniformLocation("uUseLighting"); var shaderProgram_ambientColorUniform = getUniformLocation("uAmbientColor"); var shaderProgram_lightingDirectionUniform = getUniformLocation("uLightingDirection"); var shaderProgram_directionalColorUniform = getUniformLocation("uDirectionalColor"); #endregion #endregion var mvMatrix = glMatrix.mat4.create(); var mvMatrixStack = new Stack<Float32Array>(); var pMatrix = glMatrix.mat4.create(); #region new in lesson 03 Action mvPushMatrix = delegate { var copy = glMatrix.mat4.create(); glMatrix.mat4.set(mvMatrix, copy); mvMatrixStack.Push(copy); }; Action mvPopMatrix = delegate { mvMatrix = mvMatrixStack.Pop(); }; #endregion #region setMatrixUniforms Action setMatrixUniforms = delegate { gl.uniformMatrix4fv(shaderProgram_pMatrixUniform, false, pMatrix); gl.uniformMatrix4fv(shaderProgram_mvMatrixUniform, false, mvMatrix); #region new in lesson 07 var normalMatrix = glMatrix.mat3.create(); glMatrix.mat4.toInverseMat3(mvMatrix, normalMatrix); glMatrix.mat3.transpose(normalMatrix); gl.uniformMatrix3fv(shaderProgram_nMatrixUniform, false, normalMatrix); #endregion }; #endregion #region init buffers #region cubeVertexPositionBuffer var cubeVertexPositionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); var vertices = new[]{ // Front face RED -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, // Back face YELLOW -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, // Top face GREEN -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, // Bottom face BEIGE -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, // Right face PURPLE 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, // Left face -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); var cubeVertexPositionBuffer_itemSize = 3; var cubeVertexPositionBuffer_numItems = 6 * 6; #endregion #region cubeVertexNormalBuffer - new in lesson 07 var cubeVertexNormalBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexNormalBuffer); var vertexNormals = new[]{ // Front face 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, // Back face 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, // Top face 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // Bottom face 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, // Right face 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // Left face -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexNormals), gl.STATIC_DRAW); var cubeVertexNormalBuffer_itemSize = 3; var cubeVertexNormalBuffer_numItems = 24; #endregion #region cubeVertexTextureCoordBuffer var cubeVertexTextureCoordBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexTextureCoordBuffer); var textureCoords = new float[]{ // Front face 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, // Back face 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, // Top face 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, // Bottom face 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // Right face 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, // Left face 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoords), gl.STATIC_DRAW); var cubeVertexTextureCoordBuffer_itemSize = 2; var cubeVertexTextureCoordBuffer_numItems = 24; var cubeVertexIndexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); var cubeVertexIndices = new UInt16[]{ 0, 1, 2, 0, 2, 3, // Front face 4, 5, 6, 4, 6, 7, // Back face 8, 9, 10, 8, 10, 11, // Top face 12, 13, 14, 12, 14, 15, // Bottom face 16, 17, 18, 16, 18, 19, // Right face 20, 21, 22, 20, 22, 23 // Left face }; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW); var cubeVertexIndexBuffer_itemSize = 1; var cubeVertexIndexBuffer_numItems = cubeVertexPositionBuffer_numItems; #endregion #endregion // initTexture new in lesson 05 var textures = new[] { gl.createTexture(), gl.createTexture(), gl.createTexture(), }; var xRot = 0.0f; var xSpeed = 2.0f; var yRot = 0.0f; var ySpeed = 2.0f; var z = -5.0f; var filter = 2; #region currentlyPressedKeys var currentlyPressedKeys = new Dictionary<int, bool> { {33, false}, {34, false}, {37, false}, {39, false}, {38, false}, {40, false} }; Native.Document.onkeydown += e => { currentlyPressedKeys[e.KeyCode] = true; if (e.KeyCode == 13) { filter += 1; if (filter == 3) { filter = 0; } } }; Native.Document.onkeyup += e => { currentlyPressedKeys[e.KeyCode] = false; }; #endregion new WebGLLesson07.HTML.Images.FromAssets.crate().InvokeOnComplete( texture_image => { #region handleLoadedTexture gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1); gl.bindTexture(gl.TEXTURE_2D, textures[0]); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture_image); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, (int)gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, (int)gl.NEAREST); gl.bindTexture(gl.TEXTURE_2D, textures[1]); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture_image); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, (int)gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, (int)gl.LINEAR); gl.bindTexture(gl.TEXTURE_2D, textures[2]); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture_image); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, (int)gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, (int)gl.LINEAR_MIPMAP_NEAREST); gl.generateMipmap(gl.TEXTURE_2D); gl.bindTexture(gl.TEXTURE_2D, null); #endregion gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); gl.enable(gl.DEPTH_TEST); #region animate var lastTime = 0L; Action animate = delegate { var timeNow = new IDate().getTime(); if (lastTime != 0) { var elapsed = timeNow - lastTime; xRot += (xSpeed * elapsed) / 1000.0f; yRot += (ySpeed * elapsed) / 1000.0f; } lastTime = timeNow; }; #endregion Func<float, float> degToRad = (degrees) => { return degrees * (f)Math.PI / 180f; }; #region drawScene Action drawScene = delegate { gl.viewport(0, 0, gl_viewportWidth, gl_viewportHeight); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); glMatrix.mat4.perspective(45f, (float)gl_viewportWidth / (float)gl_viewportHeight, 0.1f, 100.0f, pMatrix); glMatrix.mat4.identity(mvMatrix); glMatrix.mat4.translate(mvMatrix, new float[] { 0.0f, 0.0f, z }); glMatrix.mat4.rotate(mvMatrix, degToRad(xRot), new[] { 1f, 0f, 0f }); glMatrix.mat4.rotate(mvMatrix, degToRad(yRot), new[] { 0f, 1f, 0f }); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, cubeVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); #region new in lesson 07 gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexNormalBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexNormalAttribute, cubeVertexNormalBuffer_itemSize, gl.FLOAT, false, 0, 0); #endregion gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexTextureCoordBuffer); gl.vertexAttribPointer((uint)shaderProgram_textureCoordAttribute, cubeVertexTextureCoordBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, textures[filter]); gl.uniform1i(shaderProgram_samplerUniform, 0); #region new in lesson 07 var lighting = toolbar.lighting.@checked; gl.uniform1i(shaderProgram_useLightingUniform, lighting.ToInt32()); if (lighting) { gl.uniform3f( shaderProgram_ambientColorUniform, toolbar.ambientR, toolbar.ambientG, toolbar.ambientB ); var lightingDirection = new float[]{ toolbar.lightDirectionX, toolbar.lightDirectionY, toolbar.lightDirectionZ }; var adjustedLD = glMatrix.vec3.create(); glMatrix.vec3.normalize(lightingDirection, adjustedLD); glMatrix.vec3.scale(adjustedLD, new f[] {-1}); gl.uniform3fv(shaderProgram_lightingDirectionUniform, adjustedLD); gl.uniform3f( shaderProgram_directionalColorUniform, toolbar.directionalR, toolbar.directionalG, toolbar.directionalB ); } #endregion gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); setMatrixUniforms(); gl.drawElements(gl.TRIANGLES, cubeVertexIndexBuffer_numItems, gl.UNSIGNED_SHORT, 0); }; drawScene(); #endregion #region handleKeys Action handleKeys = delegate { if (currentlyPressedKeys[33]) { // Page Up z -= 0.05f; } if (currentlyPressedKeys[34]) { // Page Down z += 0.05f; } if (currentlyPressedKeys[37]) { // Left cursor key ySpeed -= 1f; } if (currentlyPressedKeys[39]) { // Right cursor key ySpeed += 1f; } if (currentlyPressedKeys[38]) { // Up cursor key xSpeed -= 1f; } if (currentlyPressedKeys[40]) { // Down cursor key xSpeed += 1f; } }; #endregion var c = 0; Native.window.onframe += delegate { c++; Native.document.title = "" + new { c, filter }; handleKeys(); drawScene(); animate(); }; } ); }
private void Initialize(IDefault page = null) { #region += Launched chrome.app.window dynamic self = Native.self; dynamic self_chrome = self.chrome; object self_chrome_socket = self_chrome.socket; if (self_chrome_socket != null) { if (!(Native.window.opener == null && Native.window.parent == Native.window.self)) { Console.WriteLine("chrome.app.window.create, is that you?"); // pass thru } else { // should jsc send a copresence udp message? chrome.runtime.UpdateAvailable += delegate { new chrome.Notification(title: "UpdateAvailable"); }; chrome.app.runtime.Launched += async delegate { // 0:12094ms chrome.app.window.create {{ href = chrome-extension://aemlnmcokphbneegoefdckonejmknohh/_generated_background_page.html }} Console.WriteLine("chrome.app.window.create " + new { Native.document.location.href }); new chrome.Notification(title: "ChromeUDPSendAsync"); var xappwindow = await chrome.app.window.create( Native.document.location.pathname, options: null ); //xappwindow.setAlwaysOnTop xappwindow.show(); await xappwindow.contentWindow.async.onload; Console.WriteLine("chrome.app.window loaded!"); }; return; } } #endregion int w = Native.window.Width; int h = Native.window.Height; var gl = new WebGLRenderingContext(preserveDrawingBuffer: true); var canvas = gl.canvas.AttachToDocument(); canvas.style.backgroundColor = JSColor.Black; Native.document.body.style.overflow = IStyle.OverflowEnum.hidden; canvas.style.SetLocation(0, 0); #region Dispose var IsDisposed = false; Dispose = delegate { if (IsDisposed) return; IsDisposed = true; canvas.Orphanize(); }; #endregion // http://cs.helsinki.fi/u/ilmarihe/metatunnel.html var p = gl.createProgram( new ChocoluxVertexShader(), new ChocoluxFragmentShader() ); gl.bindAttribLocation(p, 0, "position"); gl.linkProgram(p); gl.useProgram(p); var uniforms = p.Uniforms(gl); gl.viewport(0, 0, w, h); gl.enableVertexAttribArray(0); var verts = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, verts); gl.bufferData(gl.ARRAY_BUFFER, new[] { -1f, -1f, -1f, 1f, 1f, -1f, 1f, 1f } , gl.STATIC_DRAW); gl.vertexAttribPointer((uint)0, 2, gl.FLOAT, false, 0, 0); var indicies = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indicies); var q = new Uint16Array(0, 1, 2, 3); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, q, gl.STATIC_DRAW); var start = new IDate().getTime(); Native.window.onframe += delegate { var timestamp = new IDate().getTime(); var t = (timestamp - start) / 1000.0f * 30f; uniforms.t = t * 100; //gl.uniform1f(gl.getUniformLocation(p, "t"), t * 100); gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_SHORT, 0); gl.flush(); }; #region AtResize Action AtResize = delegate { if (IsDisposed) { return; } canvas.width = Native.window.Width; canvas.height = Native.window.Height; gl.viewport(0, 0, canvas.width, canvas.height); }; AtResize(); Native.window.onresize += delegate { AtResize(); }; #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 Func<string> newicon = delegate { var icon = canvas.toDataURL("image/png"); Native.Document.getElementsByTagName("link").AsEnumerable().ToList().WithEach( e => { var link = (IHTMLLink)e; if (link.rel == "icon") { if (link.type == "image/png") { link.href = icon; } else { link.Orphanize(); } } } ); return icon; }; Native.Document.body.onclick += delegate { if (IsDisposed) return; newicon(); }; #if PackageAsApplication @"Spiral".ToDocumentTitle(); Native.Window.requestAnimationFrame += delegate { var icon = newicon(); var img = new IHTMLImage { src = icon }; //img.width = Native.Window.Width / 2; //img.height = Native.Window.Height / 2; Native.Document.getElementsByTagName("script") .Select(k => (IHTMLScript)k) .FirstOrDefault(k => k.src.EndsWith("/view-source")) .With( source => { #region PackageAsApplication Action<IHTMLScript, XElement, Action<string>> PackageAsApplication = (source0, xml, yield) => { new IXMLHttpRequest( ScriptCoreLib.Shared.HTTPMethodEnum.GET, source0.src, (IXMLHttpRequest r) => { // store hash xml.Add(new XElement("link", new XAttribute("rel", "location"), new XAttribute("href", Native.Document.location.hash))); #region script xml.Add( new XElement("script", "/* source */" ) ); var data = ""; Action later = delegate { data = data.Replace("/* source */", r.responseText); }; #endregion //Native.Document.getElementsByTagName("link").AsEnumerable().ToList().ForEach( xml.Elements("link").ToList().ForEach( (XElement link, Action next) => { #region style var rel = link.Attribute("rel"); if (rel.Value != "stylesheet") { next(); return; } var href = link.Attribute("href"); var placeholder = "/* " + href.Value + " */"; //page.DragHTM.innerText += " " + placeholder; xml.Add(new XElement("style", placeholder)); new IXMLHttpRequest(ScriptCoreLib.Shared.HTTPMethodEnum.GET, href.Value, rr => { later += delegate { data = data.Replace(placeholder, rr.responseText); }; Console.WriteLine("link Remove"); link.Remove(); next(); } ); #endregion } )( delegate { data = xml.ToString(); Console.WriteLine("data: " + data); later(); yield(data); } ); } ); }; #endregion PackageAsApplication( source, XElement.Parse(new XDefaultPage.XMLSourceSource().Text), data => { var bytes = Encoding.ASCII.GetBytes(data); var data64 = System.Convert.ToBase64String(bytes); Native.Document.body.title = "Drag me!"; Native.Document.body.ondragstart += e => { //e.dataTransfer.setData("text/plain", "Sphere"); // http://codebits.glennjones.net/downloadurl/virtualdownloadurl.htm //e.dataTransfer.setData("DownloadURL", "image/png:Sphere.png:" + icon); e.dataTransfer.setData("DownloadURL", "application/octet-stream:Chocolux.htm:data:application/octet-stream;base64," + data64); e.dataTransfer.setData("text/html", data); e.dataTransfer.setData("text/uri-list", Native.Document.location + ""); e.dataTransfer.setDragImage(img, img.width / 2, img.height / 2); }; } ); } ); }; #endif }
/// <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(IApp page) { // why cant we creat svg objects yet? var h = new Hind(); h.Container.AttachTo(page.worldzoom); h.Container.style.SetLocation(800, 1200); page.world.style.transformOrigin = "800px 1400px"; var r = 0.0; var t = new IDate().getTime(); Action loop = null; var frames = 0; var ddt = 0l; loop = delegate { var tt = new IDate().getTime(); var dt = tt - t; t = tt; frames++; ddt += dt; if (ddt > 1000) { var fps = frames; Native.Document.title = new { fps }.ToString(); page.fps.innerText = "" + fps; frames = 0; ddt = 0; } r += double.Parse(page.range.value) * 0.01 * dt; //page.wings.style.transform = " rotate(" + r + "deg)"; h.wings.style.transform = " rotate(" + r + "deg)"; Native.window.requestAnimationFrame += loop; }; Native.window.requestAnimationFrame += loop; var tween_worldrotation = NumericEmitter.OfDouble( (worldrotation, y) => { page.world.style.transform = "translate(0px, -200px) rotate(" + worldrotation + "deg)"; } ); page.worldrotation.onchange += delegate { var worldrotation = int.Parse(page.worldrotation.value); worldrotation += 180; //worldrotation = worldrotation % 360; tween_worldrotation(worldrotation, 0); }; @"Hello world".ToDocumentTitle(); // Send data from JavaScript to the server tier service.WebMethod2( @"A string from JavaScript.", value => value.ToDocumentTitle() ); }
public Application(IDefault page = null) { var size = 500; var gl = new WebGLRenderingContext(); var canvas = gl.canvas.AttachToDocument(); Native.document.body.style.overflow = IStyle.OverflowEnum.hidden; canvas.style.SetLocation(0, 0, size, size); canvas.width = size; canvas.height = size; var gl_viewportWidth = size; var gl_viewportHeight = size; #region IsDisposed var IsDisposed = false; this.Dispose = delegate { if (IsDisposed) return; IsDisposed = true; canvas.Orphanize(); }; #endregion #region AtResize Action AtResize = delegate { gl_viewportWidth = Native.window.Width; gl_viewportHeight = Native.window.Height; canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportHeight); canvas.width = gl_viewportWidth; canvas.height = gl_viewportHeight; }; Native.window.onresize += e => { AtResize(); }; AtResize(); #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 #region initShaders var shaderProgram = gl.createProgram( new GeometryVertexShader(), new GeometryFragmentShader() ); gl.linkProgram(shaderProgram); gl.useProgram(shaderProgram); var shaderProgram_vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); gl.enableVertexAttribArray((uint)shaderProgram_vertexPositionAttribute); var shaderProgram_textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord"); gl.enableVertexAttribArray((uint)shaderProgram_textureCoordAttribute); var shaderProgram_pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); var shaderProgram_mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); // new in lesson 05 var shaderProgram_samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler"); #endregion var mvMatrix = glMatrix.mat4.create(); var mvMatrixStack = new Stack<Float32Array>(); var pMatrix = glMatrix.mat4.create(); #region new in lesson 03 Action mvPushMatrix = delegate { var copy = glMatrix.mat4.create(); glMatrix.mat4.set(mvMatrix, copy); mvMatrixStack.Push(copy); }; Action mvPopMatrix = delegate { mvMatrix = mvMatrixStack.Pop(); }; #endregion #region setMatrixUniforms Action setMatrixUniforms = delegate { gl.uniformMatrix4fv(shaderProgram_pMatrixUniform, false, pMatrix); gl.uniformMatrix4fv(shaderProgram_mvMatrixUniform, false, mvMatrix); }; #endregion #region init buffers #region cubeVertexPositionBuffer var cubeVertexPositionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); var vertices = new[]{ // Front face RED -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, // Back face YELLOW -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, // Top face GREEN -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, // Bottom face BEIGE -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, // Right face PURPLE 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, // Left face -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); var cubeVertexPositionBuffer_itemSize = 3; var cubeVertexPositionBuffer_numItems = 6 * 6; #endregion #region cubeVertexTextureCoordBuffer var cubeVertexTextureCoordBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexTextureCoordBuffer); var textureCoords = new float[]{ // Front face 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, // Back face 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, // Top face 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, // Bottom face 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // Right face 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, // Left face 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoords), gl.STATIC_DRAW); var cubeVertexTextureCoordBuffer_itemSize = 2; var cubeVertexTextureCoordBuffer_numItems = 24; var cubeVertexIndexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); var cubeVertexIndices = new UInt16[]{ 0, 1, 2, 0, 2, 3, // Front face 4, 5, 6, 4, 6, 7, // Back face 8, 9, 10, 8, 10, 11, // Top face 12, 13, 14, 12, 14, 15, // Bottom face 16, 17, 18, 16, 18, 19, // Right face 20, 21, 22, 20, 22, 23 // Left face }; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW); var cubeVertexIndexBuffer_itemSize = 1; var cubeVertexIndexBuffer_numItems = cubeVertexPositionBuffer_numItems; #endregion #endregion // initTexture new in lesson 05 var neheTexture = gl.createTexture(); var neheTexture_image = new WebGLLesson05.HTML.Images.FromAssets.nehe(); neheTexture_image.InvokeOnComplete( delegate { gl.bindTexture(gl.TEXTURE_2D, neheTexture); #region with neheTexture gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, neheTexture_image); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, (int)gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, (int)gl.NEAREST); #endregion gl.bindTexture(gl.TEXTURE_2D, null); gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); gl.enable(gl.DEPTH_TEST); #region new in lesson 04 var xRot = 0.0f; var yRot = 0.0f; var zRot = 0.0f; var lastTime = 0L; Action animate = delegate { var timeNow = new IDate().getTime(); if (lastTime != 0) { var elapsed = timeNow - lastTime; xRot += (90 * elapsed) / 1000.0f; yRot += (90 * elapsed) / 1000.0f; zRot += (90 * elapsed) / 1000.0f; } lastTime = timeNow; }; Func<float, float> degToRad = (degrees) => { return degrees * (f)Math.PI / 180f; }; #endregion #region drawScene Action drawScene = delegate { gl.viewport(0, 0, gl_viewportWidth, gl_viewportHeight); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); glMatrix.mat4.perspective(45f, (float)gl_viewportWidth / (float)gl_viewportHeight, 0.1f, 100.0f, pMatrix); glMatrix.mat4.identity(mvMatrix); glMatrix.mat4.translate(mvMatrix, new float[] { 0.0f, 0.0f, -5.0f }); glMatrix.mat4.rotate(mvMatrix, degToRad(xRot), new[] { 1f, 0f, 0f }); glMatrix.mat4.rotate(mvMatrix, degToRad(yRot), new[] { 0f, 1f, 0f }); glMatrix.mat4.rotate(mvMatrix, degToRad(zRot), new[] { 0f, 0f, 1f }); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, cubeVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexTextureCoordBuffer); gl.vertexAttribPointer((uint)shaderProgram_textureCoordAttribute, cubeVertexTextureCoordBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, neheTexture); gl.uniform1i(shaderProgram_samplerUniform, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); setMatrixUniforms(); gl.drawElements(gl.TRIANGLES, cubeVertexIndexBuffer_numItems, gl.UNSIGNED_SHORT, 0); }; drawScene(); #endregion var c = 0; Native.window.onframe += delegate { c++; Native.document.title = "" + c; drawScene(); animate(); }; } ); }
void InitializeContent(IDefault page = null) { var size = 500; var gl = new WebGLRenderingContext(); var canvas = gl.canvas.AttachToDocument(); Native.document.body.style.overflow = IStyle.OverflowEnum.hidden; canvas.style.SetLocation(0, 0, size, size); canvas.width = size; canvas.height = size; var gl_viewportWidth = size; var gl_viewportHeight = size; #region IsDisposed var IsDisposed = false; this.Dispose = delegate { if (IsDisposed) return; IsDisposed = true; canvas.Orphanize(); }; #endregion #region AtResize Action AtResize = delegate { gl_viewportWidth = Native.window.Width; gl_viewportHeight = Native.window.Height; canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportHeight); canvas.width = gl_viewportWidth; canvas.height = gl_viewportHeight; }; Native.window.onresize += e => { AtResize(); }; AtResize(); #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 #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 #region programs var programs = new[] { new { vs = (FragmentShader)new Shaders.PerFragmentLightingFragmentShader(), fs = (VertexShader)new Shaders.PerFragmentLightingVertexShader() }, }.Select( p => { var vs = createShader(p.vs); var fs = createShader(p.fs); var shaderProgram = gl.createProgram(); gl.attachShader(shaderProgram, vs); gl.attachShader(shaderProgram, fs); gl.linkProgram(shaderProgram); var vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); gl.enableVertexAttribArray((uint)vertexPositionAttribute); var vertexNormalAttribute = gl.getAttribLocation(shaderProgram, "aVertexNormal"); gl.enableVertexAttribArray((uint)vertexNormalAttribute); var textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord"); gl.enableVertexAttribArray((uint)textureCoordAttribute); return new { program = shaderProgram, vertexPositionAttribute, vertexNormalAttribute, textureCoordAttribute, pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"), mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"), nMatrixUniform = gl.getUniformLocation(shaderProgram, "uNMatrix"), samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler"), materialAmbientColorUniform = gl.getUniformLocation(shaderProgram, "uMaterialAmbientColor"), materialDiffuseColorUniform = gl.getUniformLocation(shaderProgram, "uMaterialDiffuseColor"), materialSpecularColorUniform = gl.getUniformLocation(shaderProgram, "uMaterialSpecularColor"), materialShininessUniform = gl.getUniformLocation(shaderProgram, "uMaterialShininess"), materialEmissiveColorUniform = gl.getUniformLocation(shaderProgram, "uMaterialEmissiveColor"), showSpecularHighlightsUniform = gl.getUniformLocation(shaderProgram, "uShowSpecularHighlights"), useTexturesUniform = gl.getUniformLocation(shaderProgram, "uUseTextures"), ambientLightingColorUniform = gl.getUniformLocation(shaderProgram, "uAmbientLightingColor"), pointLightingLocationUniform = gl.getUniformLocation(shaderProgram, "uPointLightingLocation"), pointLightingSpecularColorUniform = gl.getUniformLocation(shaderProgram, "uPointLightingSpecularColor"), pointLightingDiffuseColorUniform = gl.getUniformLocation(shaderProgram, "uPointLightingDiffuseColor"), }; } ).ToArray(); #endregion var currentProgram = programs.First(); var mvMatrix = glMatrix.mat4.create(); var mvMatrixStack = new Stack<Float32Array>(); var pMatrix = glMatrix.mat4.create(); #region mvPushMatrix Action mvPushMatrix = delegate { var copy = glMatrix.mat4.create(); glMatrix.mat4.set(mvMatrix, copy); mvMatrixStack.Push(copy); }; #endregion #region mvPopMatrix Action mvPopMatrix = delegate { mvMatrix = mvMatrixStack.Pop(); }; #endregion #region degToRad Func<float, float> degToRad = (degrees) => { return degrees * (f)Math.PI / 180f; }; #endregion #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 // await crate new HTML.Images.FromAssets.crate().InvokeOnComplete( crate => // await moon new HTML.Images.FromAssets.moon().InvokeOnComplete( moon => { #region setMatrixUniforms Action setMatrixUniforms = delegate { #region [uniform] mat4 uPMatrix <- pMatrix gl.uniformMatrix4fv(currentProgram.pMatrixUniform, false, pMatrix); #endregion #region [uniform] mat4 uMVMatrix <- mvMatrix gl.uniformMatrix4fv(currentProgram.mvMatrixUniform, false, mvMatrix); #endregion var normalMatrix = glMatrix.mat3.create(); glMatrix.mat4.toInverseMat3(mvMatrix, normalMatrix); glMatrix.mat3.transpose(normalMatrix); #region [uniform] mat3 uNMatrix <- normalMatrix gl.uniformMatrix3fv(currentProgram.nMatrixUniform, false, normalMatrix); #endregion }; #endregion #region handleLoadedTexture Action<WebGLTexture, IHTMLImage> handleLoadedTexture = (texture, texture_image) => { gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1); gl.bindTexture(gl.TEXTURE_2D, texture); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture_image); gl.texParameteri((uint)gl.TEXTURE_2D, (uint)gl.TEXTURE_MAG_FILTER, (int)gl.LINEAR); gl.texParameteri((uint)gl.TEXTURE_2D, (uint)gl.TEXTURE_MIN_FILTER, (int)gl.LINEAR_MIPMAP_NEAREST); // INVALID_OPERATION: generateMipmap: level 0 not power of 2 or not all the same size gl.generateMipmap(gl.TEXTURE_2D); gl.bindTexture(gl.TEXTURE_2D, null); }; #endregion var crateTexture = gl.createTexture(); handleLoadedTexture(crateTexture, crate); var moonTexture = gl.createTexture(); handleLoadedTexture(moonTexture, moon); #region initTextureFramebuffer var rttFramebuffer = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, rttFramebuffer); var rttFramebuffer_width = 512; var rttFramebuffer_height = 512; var rttTexture = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, rttTexture); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, (int)gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, (int)gl.LINEAR_MIPMAP_NEAREST); gl.generateMipmap(gl.TEXTURE_2D); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, rttFramebuffer_width, rttFramebuffer_height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); var renderbuffer = gl.createRenderbuffer(); gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer); gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, rttFramebuffer_width, rttFramebuffer_height); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, rttTexture, 0); gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderbuffer); gl.bindTexture(gl.TEXTURE_2D, null); gl.bindRenderbuffer(gl.RENDERBUFFER, null); gl.bindFramebuffer(gl.FRAMEBUFFER, null); #endregion #region initBuffers var cubeVertexPositionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); var vertices = new f[]{ // Front face -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, // Back face -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, // Top face -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, // Bottom face -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, // Right face 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, // Left face -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); var cubeVertexPositionBuffer_itemSize = 3; var cubeVertexPositionBuffer_numItems = 24; var cubeVertexNormalBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexNormalBuffer); var vertexNormals = new f[]{ // Front face 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, // Back face 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, // Top face 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // Bottom face 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, // Right face 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // Left face -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexNormals), gl.STATIC_DRAW); var cubeVertexNormalBuffer_itemSize = 3; var cubeVertexNormalBuffer_numItems = 24; var cubeVertexTextureCoordBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexTextureCoordBuffer); var textureCoords = new f[]{ // Front face 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, // Back face 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, // Top face 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, // Bottom face 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // Right face 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, // Left face 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoords), gl.STATIC_DRAW); var cubeVertexTextureCoordBuffer_itemSize = 2; var cubeVertexTextureCoordBuffer_numItems = 24; var cubeVertexIndexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); var cubeVertexIndices = new ushort[]{ 0, 1, 2, 0, 2, 3, // Front face 4, 5, 6, 4, 6, 7, // Back face 8, 9, 10, 8, 10, 11, // Top face 12, 13, 14, 12, 14, 15, // Bottom face 16, 17, 18, 16, 18, 19, // Right face 20, 21, 22, 20, 22, 23 // Left face }; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW); var cubeVertexIndexBuffer_itemSize = 1; var cubeVertexIndexBuffer_numItems = 36; var latitudeBands = 30; var longitudeBands = 30; var radius = 1; var vertexPositionData = new List<f>(); var normalData = new List<f>(); var textureCoordData = new List<f>(); for (var latNumber = 0; latNumber <= latitudeBands; latNumber++) { var theta = latNumber * Math.PI / latitudeBands; var sinTheta = (f)Math.Sin(theta); var cosTheta = (f)Math.Cos(theta); for (var longNumber = 0; longNumber <= longitudeBands; longNumber++) { var phi = longNumber * 2 * Math.PI / longitudeBands; var sinPhi = (f)Math.Sin(phi); var cosPhi = (f)Math.Cos(phi); var x = cosPhi * sinTheta; var y = cosTheta; var z = sinPhi * sinTheta; var u = 1 - (longNumber / longitudeBands); var v = 1 - (latNumber / latitudeBands); normalData.Add(x); normalData.Add(y); normalData.Add(z); textureCoordData.Add(u); textureCoordData.Add(v); vertexPositionData.Add(radius * x); vertexPositionData.Add(radius * y); vertexPositionData.Add(radius * z); } } var indexData = new List<ushort>(); for (var latNumber = 0; latNumber < latitudeBands; latNumber++) { for (var longNumber = 0; longNumber < longitudeBands; longNumber++) { var first = (latNumber * (longitudeBands + 1)) + longNumber; var second = first + longitudeBands + 1; indexData.Add((ushort)(first)); indexData.Add((ushort)(second)); indexData.Add((ushort)(first + 1)); indexData.Add((ushort)(second)); indexData.Add((ushort)(second + 1)); indexData.Add((ushort)(first + 1)); } } var moonVertexNormalBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexNormalBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(normalData.ToArray()), gl.STATIC_DRAW); var moonVertexNormalBuffer_itemSize = 3; var moonVertexNormalBuffer_numItems = normalData.Count / 3; var moonVertexTextureCoordBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexTextureCoordBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoordData.ToArray()), gl.STATIC_DRAW); var moonVertexTextureCoordBuffer_itemSize = 2; var moonVertexTextureCoordBuffer_numItems = textureCoordData.Count / 2; var moonVertexPositionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexPositionBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexPositionData.ToArray()), gl.STATIC_DRAW); var moonVertexPositionBuffer_itemSize = 3; var moonVertexPositionBuffer_numItems = vertexPositionData.Count / 3; var moonVertexIndexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, moonVertexIndexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexData.ToArray()), gl.STREAM_DRAW); var moonVertexIndexBuffer_itemSize = 1; var moonVertexIndexBuffer_numItems = indexData.Count; var laptopScreenVertexPositionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, laptopScreenVertexPositionBuffer); vertices = new[]{ 0.580687f, 0.659f, 0.813106f, -0.580687f, 0.659f, 0.813107f, 0.580687f, 0.472f, 0.113121f, -0.580687f, 0.472f, 0.113121f, }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); var laptopScreenVertexPositionBuffer_itemSize = 3; var laptopScreenVertexPositionBuffer_numItems = 4; var laptopScreenVertexNormalBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, laptopScreenVertexNormalBuffer); vertexNormals = new f[]{ 0.000000f, -0.965926f, 0.258819f, 0.000000f, -0.965926f, 0.258819f, 0.000000f, -0.965926f, 0.258819f, 0.000000f, -0.965926f, 0.258819f, }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexNormals), gl.STATIC_DRAW); var laptopScreenVertexNormalBuffer_itemSize = 3; var laptopScreenVertexNormalBuffer_numItems = 4; var laptopScreenVertexTextureCoordBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, laptopScreenVertexTextureCoordBuffer); textureCoords = new f[]{ 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoords), gl.STATIC_DRAW); var laptopScreenVertexTextureCoordBuffer_itemSize = 2; var laptopScreenVertexTextureCoordBuffer_numItems = 4; #endregion #region handleLoadedLaptop var laptopData = macbook; var laptopVertexNormalBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, laptopVertexNormalBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(laptopData.vertexNormals), gl.STATIC_DRAW); var laptopVertexNormalBuffer_itemSize = 3; var laptopVertexNormalBuffer_numItems = laptopData.vertexNormals.Length / 3; var laptopVertexTextureCoordBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, laptopVertexTextureCoordBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(laptopData.vertexTextureCoords), gl.STATIC_DRAW); var laptopVertexTextureCoordBuffer_itemSize = 2; var laptopVertexTextureCoordBuffer_numItems = laptopData.vertexTextureCoords.Length / 2; var laptopVertexPositionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, laptopVertexPositionBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(laptopData.vertexPositions), gl.STATIC_DRAW); var laptopVertexPositionBuffer_itemSize = 3; var laptopVertexPositionBuffer_numItems = laptopData.vertexPositions.Length / 3; var laptopVertexIndexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, laptopVertexIndexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(laptopData.indices), gl.STREAM_DRAW); var laptopVertexIndexBuffer_itemSize = 1; var laptopVertexIndexBuffer_numItems = laptopData.indices.Length; #endregion gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); gl.enable(gl.DEPTH_TEST); var moonAngle = 180f; var cubeAngle = 0f; var laptopAngle = 0f; var lastTime = 0L; #region animate Action animate = () => { var timeNow = new IDate().getTime(); if (lastTime != 0) { var elapsed = timeNow - lastTime; moonAngle += 0.05f * elapsed; cubeAngle += 0.05f * elapsed; laptopAngle -= 0.005f * elapsed; } lastTime = timeNow; }; #endregion var laptopScreenAspectRatio = 1.66f; //Func<string, f> parseFloat = Convert.ToSingle; Func<string, f> parseFloat = x => float.Parse(x); var shaderProgram = currentProgram; #region drawSceneOnLaptopScreen Action drawSceneOnLaptopScreen = delegate { gl.viewport(0, 0, rttFramebuffer_width, rttFramebuffer_height); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); glMatrix.mat4.perspective(45, laptopScreenAspectRatio, 0.1f, 100.0f, pMatrix); gl.uniform1i(shaderProgram.showSpecularHighlightsUniform, Convert.ToInt32(false)); gl.uniform3f(shaderProgram.ambientLightingColorUniform, 0.2f, 0.2f, 0.2f); gl.uniform3f(shaderProgram.pointLightingLocationUniform, 0, 0, -5); gl.uniform3f(shaderProgram.pointLightingDiffuseColorUniform, 0.8f, 0.8f, 0.8f); gl.uniform1i(shaderProgram.showSpecularHighlightsUniform, Convert.ToInt32(false)); gl.uniform1i(shaderProgram.useTexturesUniform, Convert.ToInt32(true)); gl.uniform3f(shaderProgram.materialAmbientColorUniform, 1.0f, 1.0f, 1.0f); gl.uniform3f(shaderProgram.materialDiffuseColorUniform, 1.0f, 1.0f, 1.0f); gl.uniform3f(shaderProgram.materialSpecularColorUniform, 0.0f, 0.0f, 0.0f); gl.uniform1f(shaderProgram.materialShininessUniform, 0); gl.uniform3f(shaderProgram.materialEmissiveColorUniform, 0.0f, 0.0f, 0.0f); glMatrix.mat4.identity(mvMatrix); glMatrix.mat4.translate(mvMatrix, new f[] { 0, 0, -5 }); glMatrix.mat4.rotate(mvMatrix, degToRad(30), new f[] { 1, 0, 0 }); mvPushMatrix(); glMatrix.mat4.rotate(mvMatrix, degToRad(moonAngle), new f[] { 0, 1, 0 }); glMatrix.mat4.translate(mvMatrix, new f[] { 2, 0, 0 }); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, moonTexture); gl.uniform1i(shaderProgram.samplerUniform, 0); gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram.vertexPositionAttribute, moonVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexTextureCoordBuffer); gl.vertexAttribPointer((uint)shaderProgram.textureCoordAttribute, moonVertexTextureCoordBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexNormalBuffer); gl.vertexAttribPointer((uint)shaderProgram.vertexNormalAttribute, moonVertexNormalBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, moonVertexIndexBuffer); setMatrixUniforms(); gl.drawElements(gl.TRIANGLES, moonVertexIndexBuffer_numItems, gl.UNSIGNED_SHORT, 0); mvPopMatrix(); mvPushMatrix(); glMatrix.mat4.rotate(mvMatrix, degToRad(cubeAngle), new f[] { 0, 1, 0 }); glMatrix.mat4.translate(mvMatrix, new f[] { 1.25f, 0, 0 }); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram.vertexPositionAttribute, cubeVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexNormalBuffer); gl.vertexAttribPointer((uint)shaderProgram.vertexNormalAttribute, cubeVertexNormalBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexTextureCoordBuffer); gl.vertexAttribPointer((uint)shaderProgram.textureCoordAttribute, cubeVertexTextureCoordBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, crateTexture); gl.uniform1i(shaderProgram.samplerUniform, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); setMatrixUniforms(); gl.drawElements(gl.TRIANGLES, cubeVertexIndexBuffer_numItems, gl.UNSIGNED_SHORT, 0); mvPopMatrix(); gl.bindTexture(gl.TEXTURE_2D, rttTexture); gl.generateMipmap(gl.TEXTURE_2D); gl.bindTexture(gl.TEXTURE_2D, null); }; #endregion #region drawScene Action drawScene = () => { gl.useProgram(shaderProgram.program); gl.bindFramebuffer(gl.FRAMEBUFFER, rttFramebuffer); drawSceneOnLaptopScreen(); gl.bindFramebuffer(gl.FRAMEBUFFER, null); gl.viewport(0, 0, gl_viewportWidth, gl_viewportHeight); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); glMatrix.mat4.perspective(45, gl_viewportWidth / gl_viewportHeight, 0.1f, 100.0f, pMatrix); glMatrix.mat4.identity(mvMatrix); mvPushMatrix(); glMatrix.mat4.translate(mvMatrix, new f[]{ 0, -0.4f, (float)Math.Min(0, -2.2f + __pointer_y * 0.01) } ); if (__pointer_x != 0) laptopAngle = __pointer_x + 0.01f; glMatrix.mat4.rotate(mvMatrix, degToRad(laptopAngle), new f[] { 0, 1, 0 }); glMatrix.mat4.rotate(mvMatrix, degToRad(-90), new f[] { 1, 0, 0 }); //glMatrix.mat4.rotate(mvMatrix, __pointer_y * 0.01f, 0, 1, 0); //glMatrix.mat4.rotate(mvMatrix, __pointer_x * 0.01f, 1, 0, 0); gl.uniform1i(shaderProgram.showSpecularHighlightsUniform, Convert.ToInt32(true)); gl.uniform3f(shaderProgram.pointLightingLocationUniform, -1, 2, -1); gl.uniform3f(shaderProgram.ambientLightingColorUniform, 0.2f, 0.2f, 0.2f); gl.uniform3f(shaderProgram.pointLightingDiffuseColorUniform, 0.8f, 0.8f, 0.8f); gl.uniform3f(shaderProgram.pointLightingSpecularColorUniform, 0.8f, 0.8f, 0.8f); // The laptop body is quite shiny and has no texture. It reflects lots of specular light gl.uniform3f(shaderProgram.materialAmbientColorUniform, 1.0f, 1.0f, 1.0f); gl.uniform3f(shaderProgram.materialDiffuseColorUniform, 1.0f, 1.0f, 1.0f); gl.uniform3f(shaderProgram.materialSpecularColorUniform, 1.5f, 1.5f, 1.5f); gl.uniform1f(shaderProgram.materialShininessUniform, 5); gl.uniform3f(shaderProgram.materialEmissiveColorUniform, 0.0f, 0.0f, 0.0f); gl.uniform1i(shaderProgram.useTexturesUniform, Convert.ToInt32(false)); //if (laptopVertexPositionBuffer) { gl.bindBuffer(gl.ARRAY_BUFFER, laptopVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram.vertexPositionAttribute, laptopVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, laptopVertexTextureCoordBuffer); gl.vertexAttribPointer((uint)shaderProgram.textureCoordAttribute, laptopVertexTextureCoordBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, laptopVertexNormalBuffer); gl.vertexAttribPointer((uint)shaderProgram.vertexNormalAttribute, laptopVertexNormalBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, laptopVertexIndexBuffer); setMatrixUniforms(); gl.drawElements(gl.TRIANGLES, laptopVertexIndexBuffer_numItems, gl.UNSIGNED_SHORT, 0); //} gl.uniform3f(shaderProgram.materialAmbientColorUniform, 0.0f, 0.0f, 0.0f); gl.uniform3f(shaderProgram.materialDiffuseColorUniform, 0.0f, 0.0f, 0.0f); gl.uniform3f(shaderProgram.materialSpecularColorUniform, 0.5f, 0.5f, 0.5f); gl.uniform1f(shaderProgram.materialShininessUniform, 20); gl.uniform3f(shaderProgram.materialEmissiveColorUniform, 1.5f, 1.5f, 1.5f); gl.uniform1i(shaderProgram.useTexturesUniform, Convert.ToInt32(true)); gl.bindBuffer(gl.ARRAY_BUFFER, laptopScreenVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram.vertexPositionAttribute, laptopScreenVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, laptopScreenVertexNormalBuffer); gl.vertexAttribPointer((uint)shaderProgram.vertexNormalAttribute, laptopScreenVertexNormalBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, laptopScreenVertexTextureCoordBuffer); gl.vertexAttribPointer((uint)shaderProgram.textureCoordAttribute, laptopScreenVertexTextureCoordBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, rttTexture); gl.uniform1i(shaderProgram.samplerUniform, 0); setMatrixUniforms(); gl.drawArrays(gl.TRIANGLE_STRIP, 0, laptopScreenVertexPositionBuffer_numItems); mvPopMatrix(); }; #endregion Native.window.onframe += delegate { if (IsDisposed) return; animate(); drawScene(); }; } ) ); }
private static void InitializeContent() { Action __WoodsXmasByRobert_loaded = null; Console.WriteLine( new { Native.window.opener, Native.window.parent } ); Native.window.parent.With( parent => { parent.postMessage("WoodsXmasByRobert.preparing"); Console.WriteLine("WoodsXmasByRobert.preparing"); __WoodsXmasByRobert_loaded = delegate { Console.WriteLine("will post WoodsXmasByRobert.loaded"); __WoodsXmasByRobert_loaded = null; parent.postMessage("WoodsXmasByRobert.loaded"); }; } ); //<!-- Snow flakes --> new IHTMLScript { type = "x-shader/x-vertex", id = "vertexshader", innerText = new Shaders.particlesVertexShader().ToString() }.AttachToDocument(); new IHTMLScript { type = "x-shader/x-fragment", id = "fragmentshader", innerText = new Shaders.particlesFragmentShader().ToString() }.AttachToDocument(); var w = Native.window; dynamic window = w; // http://stackoverflow.com/questions/4923136/why-doesnt-firefox-support-mp3-file-format-in-audio // Timestamp: 12/28/2012 1:22:05 PM //Warning: HTTP "Content-Type" of "audio/mpeg3" is not supported. Load of media resource http://192.168.1.100:27248/assets/WoodsXmasByRobert/unfiltered_mix.mp3 failed. //Source File: http://192.168.1.100:27248/ //Line: 0 #region snd var snd = new HTML.Audio.FromAssets.unfiltered_mix { volume = 0.9 }; window.snd = snd; Native.window.onfocus += delegate { Console.WriteLine("WoodsXmasByRobert onfocus"); snd.volume = 0.9; }; Native.window.onblur += delegate { Console.WriteLine("WoodsXmasByRobert onblur"); snd.volume = 0.1; // if we are also not visible anymore // and animations frame stop // we should stop all sound }; #endregion var canvas = new IHTMLCanvas(); object webglRenderer_args = new object().With( (dynamic a) => { a.clearColor = 0x000000; a.clearAlpha = 1.0; a.preserveDrawingBuffer = true; a.canvas = canvas; } ); var webglRenderer = new THREE.WebGLRenderer( webglRenderer_args ); webglRenderer.autoClear = false; //var canvas = (IHTMLCanvas)webglRenderer.domElement; canvas.AttachToDocument(); webglRenderer.setSize(Native.window.Width, Native.window.Height); var camera = new THREE.PerspectiveCamera(75, Native.window.Width / Native.window.Height, 1, 100000); camera.position.z = 0; camera.position.x = 0; camera.position.y = 0; window.camera = camera; var cameraTarget = new THREE.Vector3(); cameraTarget.z = -400; camera.lookAt(cameraTarget); window.cameraTarget = cameraTarget; var loadingImage = THREE.ImageUtils.loadTexture(new loading().src); var map = THREE.ImageUtils.loadTexture(new snowflake().src); var starImage = THREE.ImageUtils.loadTexture(new flare().src); window.loadingImage = loadingImage; window.map = map; window.starImage = starImage; #region cursor var cursor = new pointer(); cursor.style.zIndex = 0x1000; cursor.Hide(); cursor.AttachToDocument(); dynamic style = Native.Document.body.style; //http://stackoverflow.com/questions/7849002/how-can-i-set-the-hotspot-to-the-center-of-a-custom-cursor // http://stackoverflow.com/questions/5649608/custom-css-cursors style.cursor = "url(" + cursor.src + ") 16 16,pointer"; #endregion var mouseXpercent = 0.5; var mouseYpercent = 0.5; #region onmousemove var CursorX = 0; var CursorY = 0; Native.Document.onmousemove += e => { if (Native.Document.pointerLockElement == Native.Document.body) { cursor.Show(); CursorX += e.movementX; CursorY += e.movementY; } else { cursor.Hide(); CursorX = e.CursorX; CursorY = e.CursorY; } // keep cursor in view CursorX = CursorX.Max(0).Min(Native.window.Width); CursorY = CursorY.Max(0).Min(Native.window.Height); if (Native.document.pointerLockElement == Native.document.body) { cursor.style.SetLocation(CursorX - 16, CursorY - 16); } var windowHalfX = Native.window.Width >> 1; var windowHalfY = Native.window.Height >> 1; var mouseX = (CursorX - windowHalfX); var mouseY = (CursorY - windowHalfY); mouseXpercent = mouseX / windowHalfX; mouseYpercent = mouseY / windowHalfY; window.mouseXpercent = mouseXpercent; window.mouseYpercent = mouseYpercent; }; #endregion Native.Document.onmousedown += e => { if (e.MouseButton == IEvent.MouseButtonEnum.Right) Native.Document.body.requestPointerLock(); }; new AppCode().Content.AttachToDocument().onload += delegate { // ScriptCoreLib should define this event! snd.addEventListener( "loadeddata", new Action( delegate { new IFunction("window.checkLoadingDone();").apply(Native.window); } ) ); var scene = (THREE.Scene)(object)window.scene; scene.add(camera); #region Cloud { object args = new object().With( (dynamic a) => { a.map = THREE.ImageUtils.loadTexture(new cloud().src); a.transparent = true; a.opacity = 0.17; a.fog = false; } ); var cloudPlane = new THREE.PlaneGeometry(12500, 1880); var cloud = new THREE.Mesh(cloudPlane, new THREE.MeshBasicMaterial(args)); cloud.position.set(300, 5350, -4450); cloud.lookAt(camera.position); scene.add(cloud); window.cloud = cloud; } #endregion #region Sky { object args = new object().With( (dynamic a) => { a.map = THREE.ImageUtils.loadTexture(new sky().src); a.opacity = 0.57; a.fog = false; } ); var skyPlane = new THREE.PlaneGeometry(9000, 6000); var sky = new THREE.Mesh(skyPlane, new THREE.MeshBasicMaterial(args)); sky.scale.set(4, 2.5, 2.5); sky.position.set(0, 7500, -6000); sky.lookAt(camera.position); scene.add(sky); window.sky = sky; } #endregion #region moon { dynamic moon_material_args = new object(); moon_material_args.map = THREE.ImageUtils.loadTexture(new moon().src); moon_material_args.transparent = true; moon_material_args.opacity = 0.3; moon_material_args.fog = false; moon_material_args.blending = THREE.AdditiveBlending; var moonPlane = new THREE.PlaneGeometry(1000, 1000); var moon = new THREE.Mesh(moonPlane, new THREE.MeshBasicMaterial( (object)moon_material_args ) ); moon.position.set(300, 4300, -4600); moon.lookAt(camera.position); scene.add(moon); window.moon = moon; } #endregion #region subtitleArray var subtitleArray = (IArray<THREE.Mesh>)(object)window.subtitleArray; var textPlane = new THREE.PlaneGeometry(512, 80); new SubtitlesImages().Images.WithEach( i => { object args = new object().With( (dynamic a) => { a.map = THREE.ImageUtils.loadTexture(i.src); a.transparent = true; a.depthTest = false; } ); var sub = new THREE.Mesh(textPlane, new THREE.MeshBasicMaterial(args)); sub.position.z = -800; sub.position.y = -550; sub.visible = false; camera.add(sub); subtitleArray.push(sub); } ); { var endPlane = new THREE.PlaneGeometry(500, 100); object args = new object().With( (dynamic a) => { a.map = THREE.ImageUtils.loadTexture(new xmas().src); a.transparent = true; a.opacity = 1.0; a.depthTest = false; } ); var end = new THREE.Mesh(endPlane, new THREE.MeshBasicMaterial(args)); end.position.z = -400; end.position.y = 100; end.visible = false; camera.add(end); subtitleArray.push(end); window.end = end; } new IFunction("window.setupSubtitles();").apply(Native.window); #endregion var particles = (THREE.ParticleSystem)(object)window.particles; var bgSprite = (THREE.Sprite)(object)window.bgSprite; var loadingSprite = (THREE.Sprite)(object)window.loadingSprite; var pointLight = (THREE.PointLight)(object)window.pointLight; var treeArray = (IArray<THREE.Mesh>)(object)window.treeArray; var rockArray = (IArray<THREE.Mesh>)(object)window.rockArray; var flowerArray = (IArray<THREE.Mesh>)(object)window.flowerArray; var groundMesh1 = (THREE.Mesh)(object)window.groundMesh1; var groundMesh2 = (THREE.Mesh)(object)window.groundMesh2; var renderModel = (object)window.renderModel; var effectFilm = (object)window.effectFilm; var effectVignette = (object)window.effectVignette; var effectCopy = (object)window.effectCopy; var composer = new THREE.EffectComposer(webglRenderer); composer.addPass(renderModel); composer.addPass(effectFilm); composer.addPass(effectVignette); composer.addPass(effectCopy); var speedEffector_value = (int)new IFunction("return window.speedEffector.value;").apply(Native.window); #region load Action<string, Action<object>> load = (src, yield) => { new THREE.JSONLoader().load( src, IFunction.OfDelegate(yield) ); }; #endregion #region sled load( new WoodsXmasByRobert.Design.models.sleigh().Content.src, geometry => { Console.WriteLine("got sled!"); var sled = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial() ); var scale = 4; sled.scale.set(scale, scale, scale); sled.rotation.y = -Math.PI / 2; sled.position.y = -290; sled.position.z = -80; scene.add(sled); window.sled = sled; new IFunction("window.checkLoadingDone();").apply(Native.window); } ); #endregion var random = new Random(); #region treeDead load( new WoodsXmasByRobert.Design.models.treeDead().Content.src, tree1Geo => { Console.WriteLine("got treeDead!"); load( new WoodsXmasByRobert.Design.models.treeEvergreenHigh().Content.src, tree2Geo => { Console.WriteLine("got treeEvergreenHigh!"); var gridSize = 500; for (var x = 0; x < 8; x++) { for (var z = 0; z < 12; z++) { var geo = tree2Geo; if (random.NextDouble() < 0.25) if (x != 0 && x != 7) { geo = tree1Geo; } var mesh = new THREE.Mesh(geo, new THREE.MeshFaceMaterial()); var scale = 1.2 + random.NextDouble(); mesh.scale.set(scale, scale * 2, scale); var posx = 0.0; if (x < 4) { posx = (x * gridSize) - (gridSize * 4) - 100 + random.NextDouble() * 100 - 50; } else { posx = (x * gridSize) - 1400 + random.NextDouble() * 100 - 50; }; var posz = -(z * gridSize) + random.NextDouble() * 100 - 50; mesh.position.set(posx, -400 - (random.NextDouble() * 80), posz); mesh.rotation.set((random.NextDouble() * 0.2) - 0.1, random.NextDouble() * Math.PI, (random.NextDouble() * 0.2) - 0.1); scene.add(mesh); treeArray.push(mesh); } } new IFunction("window.checkLoadingDone();").apply(Native.window); } ); } ); #endregion #region bird load( new WoodsXmasByRobert.Design.models.eagle().Content.src, geometry => { Console.WriteLine("got bird!"); dynamic args = new object(); args.color = 0x000000; args.morphTargets = true; args.fog = false; var bird = new THREE.MorphAnimMesh( geometry, new THREE.MeshBasicMaterial( (object)args ) ); bird.duration = 1000; bird.scale.set(4, 4, 4); bird.rotation.y = Math.PI; bird.position.set(0, 3000, -1500); scene.add(bird); window.bird = bird; new IFunction("window.checkLoadingDone();").apply(Native.window); } ); #endregion #region rock load( new WoodsXmasByRobert.Design.models.rock().Content.src, geometry => { Console.WriteLine("got rock!"); var numOfRocks = 25; for (var i = 0; i < numOfRocks; ++i) { dynamic args = new object(); args.color = 0x444444; var mesh = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial((object)args)); var scale = 1 + (random.NextDouble() * 0.5); mesh.scale.set(scale, scale, scale); mesh.rotation.set(0, random.NextDouble() * Math.PI, 0); mesh.position.set((random.NextDouble() * 4000) - 2000, -400, (random.NextDouble() * 6000) - 6000); if (mesh.position.x < 45) if (mesh.position.x > 0) { mesh.position.x += 450; } if (mesh.position.x > -450) if (mesh.position.x < 0) { mesh.position.x -= 450; } scene.add(mesh); rockArray.push(mesh); } new IFunction("window.checkLoadingDone();").apply(Native.window); } ); #endregion #region horse load( new WoodsXmasByRobert.Design.models.horse().Content.src, geometry => { Console.WriteLine("got horse!"); dynamic horse_material_args = new object(); horse_material_args.color = 0x090601; horse_material_args.morphTargets = true; var horse = new THREE.MorphAnimMesh(geometry, new THREE.MeshLambertMaterial( (object)horse_material_args ) ); horse.duration = 1000; horse.scale.set(2.5, 1.8, 2); horse.rotation.y = Math.PI; horse.position.set(0, -350, -700); scene.add(horse); window.horse = horse; //checkLoadingDone(); // Handles var plane = new THREE.PlaneGeometry(700, 10, 40, 1); var l = Math.Floor(plane.vertices.Length / 2.0); for (var i = 0; i < l; i++) { var offset = Math.Sin(i / 14) * 100; plane.vertices[i].y -= offset; plane.vertices[i + 41].y -= offset; plane.vertices[i].z -= (i / 5) + (offset * -1) / 8; plane.vertices[i + 41].z += (i / 5) - (offset * -1) / 8; } dynamic material_args = new object(); material_args.color = 0x090601; material_args.side = THREE.DoubleSide; var material = new THREE.MeshBasicMaterial( (object)material_args ); var leftHandle = new THREE.Mesh(plane, material); leftHandle.position.y = -120; leftHandle.position.z = -350; leftHandle.position.x = -30; leftHandle.rotation.y = -(Math.PI / 2) + 0.075; leftHandle.rotation.x = Math.PI * 2 - 0.075; scene.add(leftHandle); window.leftHandle = leftHandle; var rightHandle = new THREE.Mesh(plane, material); rightHandle.position.y = -120; rightHandle.position.z = -350; rightHandle.position.x = 30; rightHandle.rotation.y = -(Math.PI / 2) - 0.075; rightHandle.scale.z = -1; rightHandle.rotation.x = Math.PI * 2 - 0.075; scene.add(rightHandle); window.rightHandle = rightHandle; new IFunction("window.checkLoadingDone();").apply(Native.window); } ); #endregion #region flowerLoaded Action<object, bool> flowerLoaded = (geometry, halfScale) => { var numOfFlowers = 20; var half = Math.Floor(numOfFlowers / 2.0); dynamic args = new object(); args.color = 0x444444; for (var i = 0; i < half; ++i) { var mesh = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial( (object)args ) ); var scale = 1 + (random.NextDouble() * 1); if (halfScale) { scale *= 0.6; } mesh.scale.set(scale, scale, scale); mesh.rotation.set((random.NextDouble() * 0.6) - 0.3, random.NextDouble() * Math.PI, (random.NextDouble() * 0.6) - 0.3); mesh.position.set((random.NextDouble() * 1000) - 500, -310, (random.NextDouble() * 6000) - 6000); if (mesh.position.x < 100) if (mesh.position.x > 0) { mesh.position.x += 100; } if (mesh.position.x > -100) if (mesh.position.x < 0) { mesh.position.x -= 100; } scene.add(mesh); flowerArray.push(mesh); } new IFunction("window.checkLoadingDone();").apply(Native.window); }; #endregion #region weeds01 load( new WoodsXmasByRobert.Design.models.weeds01().Content.src, geometry => { Console.WriteLine("got weeds01!"); flowerLoaded(geometry, false); } ); #endregion #region glowbulb load( new WoodsXmasByRobert.Design.models.glowbulb().Content.src, geometry => { Console.WriteLine("got glowbulb!"); flowerLoaded(geometry, true); } ); #endregion #region run Action<double> run = delta => { // trees var mesh = default(THREE.Mesh); for (var i = 0; i < treeArray.length; ++i) { mesh = treeArray[i]; // respawn if (mesh.position.z > camera.position.z + 700) { mesh.position.z -= 6000; var scale = 1.2 + random.NextDouble(); mesh.scale.set(scale, scale * 2, scale); } } // rocks for (var i = 0; i < rockArray.length; ++i) { mesh = rockArray[i]; // respawn if (mesh.position.z > camera.position.z + 400) { mesh.position.z -= 6000; } } // flowers for (var i = 0; i < flowerArray.length; ++i) { mesh = flowerArray[i]; // respawn if (mesh.position.z > camera.position.z + 400) { mesh.position.z -= 6000; } } // ground respawn if (groundMesh1.position.z - 10000 > camera.position.z) { groundMesh1.position.z -= 40000; } if (groundMesh2.position.z - 10000 > camera.position.z) { groundMesh2.position.z -= 40000; } }; #endregion var oldTime = new IDate().getTime(); var r = 0.0; bool disableNextFrame = false; #region loop Action loop = delegate { var allLoaded = (bool)(object)window.allLoaded; var horse = (THREE.MorphAnimMesh)(object)window.horse; var bird = (THREE.MorphAnimMesh)(object)window.bird; var leftHandle = (THREE.Mesh)(object)window.leftHandle; var rightHandle = (THREE.Mesh)(object)window.rightHandle; var moon = (THREE.Mesh)(object)window.moon; var cloud = (THREE.Mesh)(object)window.cloud; var sky = (THREE.Mesh)(object)window.sky; var sled = (THREE.Mesh)(object)window.sled; //new IFunction("this.loop();").apply(Native.Window); var time = new IDate().getTime(); var delta = time - oldTime; oldTime = time; if (double.IsNaN(delta)) { delta = 1000 / 60; } var maxSpeed = delta / 2; if (allLoaded) { r += delta / 2000; run(delta); var noise = random.NextDouble() * 2; camera.position.x = (50 * Math.Cos(r * 2)) * speedEffector_value; camera.position.y = (2 * Math.Sin(r * 12) - 100) * speedEffector_value; camera.up.x = (Math.Sin(r * 12) / 50) * speedEffector_value; cameraTarget.y += (((camera.position.y + 80) + noise - mouseYpercent * 120) - cameraTarget.y) / 20; cameraTarget.x += (mouseXpercent * 400 - cameraTarget.x) / 20; var speed = (delta / 2) * speedEffector_value; camera.position.z -= speed; cameraTarget.z -= speed; camera.lookAt(cameraTarget); pointLight.position.z -= speed; if (moon != null) { moon.position.z -= speed; } if (cloud != null) { cloud.position.z -= speed; } if (sky != null) { sky.position.z -= speed; } #region sled if (sled != null) { sled.position.z -= speed; sled.position.x = camera.position.x; } #endregion #region bird if (bird != null) { bird.position.x = 200 * Math.Cos(r) + ((bird.position.z - camera.position.z) / 10); bird.position.y = 4000 + (Math.Sin(r) * 300); bird.position.z -= maxSpeed * 1.25; if (bird.position.z < camera.position.z - 10000) { bird.position.z = camera.position.z - 500; } bird.updateAnimation(delta); } #endregion #region horse if (horse != null) { horse.position.z -= speed; horse.position.x = camera.position.x; horse.updateAnimation(speed * 2); leftHandle.position.z -= speed; leftHandle.position.x = camera.position.x - 37; rightHandle.position.z -= speed; rightHandle.position.x = camera.position.x + 40; leftHandle.scale.y = 1 - Math.Abs(Math.Sin(camera.position.z / 150)) / 4; rightHandle.scale.y = leftHandle.scale.y; } #endregion particles.position.z -= speed; new IFunction("e", "window.uniforms.globalTime.value += e;").apply(Native.window, delta * 0.00015); new IFunction("e", "window.uniforms.speed.value = e;").apply(Native.window, speed / maxSpeed); new IFunction("window.runSubtitles();").apply(Native.window); //disableNextFrame = true; if (__WoodsXmasByRobert_loaded != null) __WoodsXmasByRobert_loaded(); } else { if (loadingSprite != null) { loadingSprite.position.set(Native.window.Width >> 1, Native.window.Height >> 1, 0); loadingSprite.rotation -= 0.08; } } if (bgSprite != null) { bgSprite.position.set(Native.window.Width >> 1, Native.window.Height >> 1, 0); } new IFunction("window.TWEEN.update();").apply(Native.window); //if (has_gl) { webglRenderer.clear(); composer.render(0.01); } }; #endregion #region animate Native.window.onframe += delegate { if (disableNextFrame) return; loop(); }; #endregion Action AtResize = delegate { // notify the renderer of the size change webglRenderer.setSize(Native.window.Width, Native.window.Height); // update the camera camera.aspect = Native.window.Width / Native.window.Height; camera.updateProjectionMatrix(); }; #region onresize Native.window.onresize += delegate { AtResize(); }; #endregion AtResize(); }; Native.Document.body.ondblclick += delegate { Native.Document.body.requestFullscreen(); }; Native.Document.body.onmousedown += e => { if (e.MouseButton == IEvent.MouseButtonEnum.Middle) { if (Native.Document.pointerLockElement == Native.Document.body) { // cant requestFullscreen while pointerLockElement Console.WriteLine("exitPointerLock"); Native.Document.exitPointerLock(); Native.Document.exitFullscreen(); return; } Native.Document.body.requestFullscreen(); Native.Document.body.requestPointerLock(); } }; Native.Document.oncontextmenu += e => { e.preventDefault(); }; }
/// <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 size = 600; var gl = new WebGLRenderingContext(); var canvas = gl.canvas.AttachToDocument(); Native.document.body.style.overflow = IStyle.OverflowEnum.hidden; canvas.style.SetLocation(0, 0, size, size); canvas.width = size; canvas.height = size; var gl_viewportWidth = size; var gl_viewportHeight = size; // can AssetLibrary create a special type // and define the variables // for it we need to parse glsl? // Geometry var shaderProgram = gl.createProgram( new GeometryVertexShader(), new GeometryFragmentShader() ); gl.linkProgram(shaderProgram); gl.useProgram(shaderProgram); var shaderProgram_vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); gl.enableVertexAttribArray((uint)shaderProgram_vertexPositionAttribute); // new in lesson 02 var shaderProgram_vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor"); gl.enableVertexAttribArray((uint)shaderProgram_vertexColorAttribute); var shaderProgram_pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); var shaderProgram_mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); // https://hacks.mozilla.org/2014/10/introducing-simd-js/ // https://github.com/toji/gl-matrix/blob/master/src/gl-matrix/mat4.js // http://www.i-programmer.info/news/167-javascript/8578-chrome-to-support-simdjs.html // https://code.google.com/p/v8/issues/detail?id=2228 var SIMD_mat4 = new System.Numerics.Matrix4x4(); var SIMD_mat4s = new Stack<System.Numerics.Matrix4x4>(); // can we convert this code to NDK friendly non GC library? // for gearVR 90FOV and cardboard wearality 150FOV #region __mat4 var __mat4 = new { // X:\jsc.svn\examples\javascript\Test\TestFloatArray\TestFloatArray\Application.cs // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2015/20150706/20150708 // generic in the sens of caller choosing is the return type a new struct or out ref? perspective = new Func<float[], float, float, float, float, float[]>( (that, fovy, aspect, near, far) => { var f = 1.0f / (float)Math.Tan(fovy / 2f); var nf = 1f / (near - far); that[0] = f / aspect; that[1] = 0; that[2] = 0; that[3] = 0; that[4] = 0; that[5] = f; that[6] = 0; that[7] = 0; that[8] = 0; that[9] = 0; that[10] = (far + near) * nf; that[11] = -1; that[12] = 0; that[13] = 0; that[14] = (2 * far * near) * nf; that[15] = 0; return that; }), // reset content of mat4 identity = new Func<float[], float[]>( that => { //Array.Copy() //var xx =&that; var x = new float[] { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, }; //is this the best way to update array contents? x.CopyTo(that, 0); return x; } ), create = new Func<float[]>( () => //new mat4() new float[] { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, } ), #region not used? clone = new Func<float[], float[]>( smat4 => //new mat4() new float[] { smat4[0], smat4[1], smat4[2], smat4[3], smat4[4], smat4[5], smat4[6], smat4[7], smat4[8], smat4[9], smat4[10], smat4[11], smat4[12], smat4[13], smat4[14], smat4[15], } ) #endregion , // X:\jsc.svn\examples\java\android\vr\OVRWindWheelNDK\OVRWindWheelNDK\References\VrApi.ovrMatrix4f.cs translate = new Func<float[], float[], float[], float[]>( (float[] that, float[] output, float[] xyz) => { float x = xyz[0], y = xyz[1], z = xyz[2]; if (output == that) { that[12] = output[0] * x + output[4] * y + output[8] * z + output[12]; that[13] = output[1] * x + output[5] * y + output[9] * z + output[13]; that[14] = output[2] * x + output[6] * y + output[10] * z + output[14]; that[15] = output[3] * x + output[7] * y + output[11] * z + output[15]; return that; } float a00, a01, a02, a03, a10, a11, a12, a13, a20, a21, a22, a23; a00 = output[0]; a01 = output[1]; a02 = output[2]; a03 = output[3]; a10 = output[4]; a11 = output[5]; a12 = output[6]; a13 = output[7]; a20 = output[8]; a21 = output[9]; a22 = output[10]; a23 = output[11]; that[0] = a00; that[1] = a01; that[2] = a02; that[3] = a03; that[4] = a10; that[5] = a11; that[6] = a12; that[7] = a13; that[8] = a20; that[9] = a21; that[10] = a22; that[11] = a23; that[12] = a00 * x + a10 * y + a20 * z + output[12]; that[13] = a01 * x + a11 * y + a21 * z + output[13]; that[14] = a02 * x + a12 * y + a22 * z + output[14]; that[15] = a03 * x + a13 * y + a23 * z + output[15]; return that; } ), rotate = new Func<float[], float[], float, float[], float[]>( (that, a, rad, axis) => { float x = axis[0], y = axis[1], z = axis[2]; float len = (float)Math.Sqrt(x * x + y * y + z * z), s, c, t, a00, a01, a02, a03, a10, a11, a12, a13, a20, a21, a22, a23, b00, b01, b02, b10, b11, b12, b20, b21, b22; if (Math.Abs(len) < float.Epsilon) return that; len = 1f / len; x *= len; y *= len; z *= len; s = (float)Math.Sin(rad); c = (float)Math.Cos(rad); t = 1 - c; a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3]; a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7]; a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11]; // Construct the elements of the rotation matrix b00 = x * x * t + c; b01 = y * x * t + z * s; b02 = z * x * t - y * s; b10 = x * y * t - z * s; b11 = y * y * t + c; b12 = z * y * t + x * s; b20 = x * z * t + y * s; b21 = y * z * t - x * s; b22 = z * z * t + c; // Perform rotation-specific matrix multiplication that[0] = a00 * b00 + a10 * b01 + a20 * b02; that[1] = a01 * b00 + a11 * b01 + a21 * b02; that[2] = a02 * b00 + a12 * b01 + a22 * b02; that[3] = a03 * b00 + a13 * b01 + a23 * b02; that[4] = a00 * b10 + a10 * b11 + a20 * b12; that[5] = a01 * b10 + a11 * b11 + a21 * b12; that[6] = a02 * b10 + a12 * b11 + a22 * b12; that[7] = a03 * b10 + a13 * b11 + a23 * b12; that[8] = a00 * b20 + a10 * b21 + a20 * b22; that[9] = a01 * b20 + a11 * b21 + a21 * b22; that[10] = a02 * b20 + a12 * b21 + a22 * b22; that[11] = a03 * b20 + a13 * b21 + a23 * b22; if (a != that) { // If the source and destination differ, copy the unchanged last row that[12] = a[12]; that[13] = a[13]; that[14] = a[14]; that[15] = a[15]; } return that; } ) }; #endregion // set to identity var mvMatrix = __mat4.create(); var mvMatrixStack = new Stack<float[]>(); // set to perspective var pMatrix = __mat4.create(); #region new in lesson 03 // how would this translate to non GC, NDK? Action mvPushMatrix = delegate { var copy = __mat4.create(); mvMatrix.CopyTo(copy, 0); //glMatrix.mat4.set(mvMatrix, copy); mvMatrixStack.Push(copy); }; Action mvPopMatrix = delegate { mvMatrix = mvMatrixStack.Pop(); }; #endregion #region setMatrixUniforms Action setMatrixUniforms = delegate { gl.uniformMatrix4fv(shaderProgram_pMatrixUniform, false, pMatrix); gl.uniformMatrix4fv(shaderProgram_mvMatrixUniform, false, mvMatrix); }; #endregion #region init buffers #region cube var cubeVertexPositionBuffer = new WebGLBuffer(gl); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); var cubesize = 1.0f * 0.05f; var vertices = new[]{ // Front face -cubesize, -cubesize, cubesize, cubesize, -cubesize, cubesize, cubesize, cubesize, cubesize, -cubesize, cubesize, cubesize, // Back face -cubesize, -cubesize, -cubesize, -cubesize, cubesize, -cubesize, cubesize, cubesize, -cubesize, cubesize, -cubesize, -cubesize, // Top face -cubesize, cubesize, -cubesize, -cubesize, cubesize, cubesize, cubesize, cubesize, cubesize, cubesize, cubesize, -cubesize, // Bottom face -cubesize, -cubesize, -cubesize, cubesize, -cubesize, -cubesize, cubesize, -cubesize, cubesize, -cubesize, -cubesize, cubesize, // Right face cubesize, -cubesize, -cubesize, cubesize, cubesize, -cubesize, cubesize, cubesize, cubesize, cubesize, -cubesize, cubesize, // Left face -cubesize, -cubesize, -cubesize, -cubesize, -cubesize, cubesize, -cubesize, cubesize, cubesize, -cubesize, cubesize, -cubesize }; gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); var cubeVertexPositionBuffer_itemSize = 3; var cubeVertexPositionBuffer_numItems = 6 * 6; var squareVertexColorBuffer = new WebGLBuffer(gl); gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexColorBuffer); // 216, 191, 18 var colors = new[]{ 1.0f, 0.6f, 0.0f, 1.0f, // Front face 1.0f, 0.6f, 0.0f, 1.0f, // Front face 1.0f, 0.6f, 0.0f, 1.0f, // Front face 1.0f, 0.6f, 0.0f, 1.0f, // Front face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Left face 1.0f, 0.8f, 0.0f, 1.0f, // Left face 1.0f, 0.8f, 0.0f, 1.0f, // Left face 1.0f, 0.8f, 0.0f, 1.0f // Left face }; gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW); var cubeVertexColorBuffer_itemSize = 4; var cubeVertexColorBuffer_numItems = 24; // ELEMENT_ARRAY_BUFFER : WebGLBuffer? // drawElements var cubeVertexIndexBuffer = new WebGLBuffer(gl); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); //var cubeVertexIndices = new UInt16[]{ var cubeVertexIndices = new byte[]{ 0, 1, 2, 0, 2, 3, // Front face 4, 5, 6, 4, 6, 7, // Back face 8, 9, 10, 8, 10, 11, // Top face 12, 13, 14, 12, 14, 15, // Bottom face 16, 17, 18, 16, 18, 19, // Right face 20, 21, 22, 20, 22, 23 // Left face }; // ushort[]? //gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndices, gl.STATIC_DRAW); var cubeVertexIndexBuffer_itemSize = 1; var cubeVertexIndexBuffer_numItems = 36; #endregion #endregion gl.clearColor(0.0f, 0.0f, 0.0f, alpha: 1.0f); gl.enable(gl.DEPTH_TEST); var rWindDelta = 0.0f; var rCubeDelta = 1.0f; if (page != null) { #region WindLeft page.WindLeft.onmousedown += delegate { rWindDelta = -2.0f; }; page.WindLeft.onmouseup += delegate { rWindDelta = 0.0f; }; #endregion #region WindRight page.WindRight.onmousedown += delegate { rWindDelta = 2.0f; }; page.WindRight.onmouseup += delegate { rWindDelta = 0.0f; }; #endregion #region SpeedSlow page.SpeedSlow.onmousedown += delegate { rCubeDelta = 0.1f; }; page.SpeedSlow.onmouseup += delegate { rCubeDelta = 1.0f; }; #endregion #region SpeedFast page.SpeedFast.onmousedown += delegate { rCubeDelta = 4.0f; }; page.SpeedFast.onmouseup += delegate { rCubeDelta = 1.0f; }; #endregion } #region animate var rCube = 0f; var rWind = 0f; var lastTime = 0L; Action animate = delegate { var timeNow = new IDate().getTime(); if (lastTime != 0) { var elapsed = timeNow - lastTime; rCube -= ((75 * elapsed) / 1000.0f) * rCubeDelta; rWind -= ((75 * elapsed) / 1000.0f) * rWindDelta; } lastTime = timeNow; }; #endregion #region degToRad Func<float, float> degToRad = (degrees) => { return degrees * (f)Math.PI / 180f; }; #endregion #region drawScene Action drawScene = delegate { gl.viewport(0, 0, gl_viewportWidth, gl_viewportHeight); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); // glMatrix.mat4.perspective( // 45f, // (float)gl_viewportWidth / (float)gl_viewportHeight, // 0.1f, // 100.0f, // pMatrix //); __mat4.perspective( pMatrix, 45f, (float)gl_viewportWidth / (float)gl_viewportHeight, 0.1f, 100.0f ); __mat4.identity(mvMatrix); //glMatrix.mat4.identity(mvMatrix); __mat4.translate(mvMatrix, mvMatrix, new float[] { -1.5f, 0.0f, -7.0f }); //glMatrix.mat4.translate(mvMatrix, new float[] { -1.5f, 0.0f, -7.0f }); mvPushMatrix(); //glMatrix.mat4.rotate(mvMatrix, degToRad(rWind), new float[] { 0f, 1f, 0f }); __mat4.rotate(mvMatrix, mvMatrix, degToRad(rWind), new float[] { 0, 1f, 0f }); #region DrawFrameworkWingAtX Action<float, float> DrawFrameworkWingAtX = (WingX, WingY) => { #region draw center cube mvPushMatrix(); __mat4.translate(mvMatrix, mvMatrix, new float[] { cubesize * WingX, cubesize * WingY, 0 }); //glMatrix.mat4.translate(mvMatrix, new float[] { cubesize * WingX, cubesize * WingY, 0 }); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, cubeVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexColorBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); setMatrixUniforms(); //gl.drawElements(gl.TRIANGLES, cubeVertexPositionBuffer_numItems, gl.UNSIGNED_SHORT, 0); gl.drawElements(gl.TRIANGLES, cubeVertexPositionBuffer_numItems, gl.UNSIGNED_BYTE, 0); mvPopMatrix(); #endregion }; #endregion #region DrawWingAtX Action<int, int, float, float> DrawWingAtX = (WingX, WingSize, WingRotationMultiplier, WingRotationOffset) => { mvPushMatrix(); __mat4.translate(mvMatrix, mvMatrix, new float[] { cubesize * WingX, 0, 0 }); //glMatrix.mat4.translate(mvMatrix, new float[] { cubesize * WingX, 0, 0 }); if (WingRotationOffset == 0) { DrawFrameworkWingAtX(0, 0); } #region DrawWingPart Action<float> DrawWingPart = PartIndex => { mvPushMatrix(); //glMatrix.mat4.rotate(mvMatrix, degToRad(WingRotationOffset + (rCube * WingRotationMultiplier)), new float[] { 1f, 0f, 0f }); __mat4.rotate(mvMatrix, mvMatrix, degToRad(WingRotationOffset + (rCube * WingRotationMultiplier)), new float[] { 1f, 0f, 0f }); //glMatrix.mat4.translate(mvMatrix, new float[] { 0f, cubesize * PartIndex * 2, 0 }); __mat4.translate(mvMatrix, mvMatrix, new float[] { 0f, cubesize * PartIndex * 2, 0 }); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, cubeVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexColorBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); setMatrixUniforms(); //gl.drawElements(gl.TRIANGLES, cubeVertexPositionBuffer_numItems, gl.UNSIGNED_SHORT, 0); gl.drawElements(gl.TRIANGLES, cubeVertexPositionBuffer_numItems, gl.UNSIGNED_BYTE, 0); mvPopMatrix(); }; #endregion #region DrawWingWithSize Action<int> DrawWingWithSize = length => { for (int i = 4; i < length; i++) { DrawWingPart(i * 1.0f); DrawWingPart(-i * 1.0f); } }; #endregion DrawWingWithSize(WingSize); mvPopMatrix(); }; #endregion var x = 8; DrawFrameworkWingAtX(x - 8, 0); for (int i = 0; i < 24; i++) { DrawFrameworkWingAtX(x - 8, -2.0f * i); } DrawWingAtX(x - 6, 0, 1f, 0); DrawWingAtX(x - 4, 0, 1f, 0); DrawWingAtX(x - 2, 0, 1f, 0); DrawWingAtX(x + 0, 16, 1f, 0); DrawWingAtX(x + 0, 16, 1f, 30); DrawWingAtX(x + 0, 16, 1f, 60); DrawWingAtX(x + 0, 16, 1f, 90); DrawWingAtX(x + 0, 16, 1f, 120); DrawWingAtX(x + 0, 16, 1f, 150); DrawWingAtX(x + 2, 0, 1f, 0); DrawWingAtX(x + 4, 0, 1f, 0); DrawWingAtX(x + 6, 0, 1f, 0); DrawWingAtX(x + 8, 12, 0.4f, 0); DrawWingAtX(x + 8, 12, 0.4f, 60); DrawWingAtX(x + 8, 12, 0.4f, 120); DrawWingAtX(x + 8 + 2, 0, 1f, 0); DrawWingAtX(x + 8 + 4, 0, 1f, 0); DrawWingAtX(x + 8 + 6, 0, 1f, 0); DrawWingAtX(x + 16, 8, 0.3f, 0); DrawWingAtX(x + 16, 8, 0.3f, 90); mvPopMatrix(); #region draw cube on the right to remind where we started //glMatrix.mat4.translate(mvMatrix, new float[] { 3.0f, 2.0f, 0.0f }); __mat4.translate(mvMatrix, mvMatrix, new float[] { 3.0f, 2.0f, 0.0f }); mvPushMatrix(); //glMatrix.mat4.rotate(mvMatrix, degToRad(rCube), new float[] { 1f, 1f, 1f }); __mat4.rotate(mvMatrix, mvMatrix, degToRad(rCube), new float[] { 1f, 1f, 1f }); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, cubeVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexColorBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); setMatrixUniforms(); //gl.drawElements(gl.TRIANGLES, cubeVertexPositionBuffer_numItems, gl.UNSIGNED_SHORT, 0); gl.drawElements(gl.TRIANGLES, cubeVertexPositionBuffer_numItems, gl.UNSIGNED_BYTE, 0); mvPopMatrix(); #endregion }; drawScene(); #endregion #region AtResize Action AtResize = delegate { gl_viewportWidth = Native.window.Width; gl_viewportHeight = Native.window.Height; canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportHeight); canvas.width = gl_viewportWidth; canvas.height = gl_viewportHeight; }; Native.window.onresize += e => { AtResize(); }; AtResize(); #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; #region tick Native.window.onframe += e => { if (IsDisposed) return; //c++; // frameID Native.document.title = "" + e.counter; drawScene(); animate(); }; #endregion if (page != null) page.Mission.Orphanize().AttachToDocument().style.SetLocation(left: size - 56, top: 16); }
// http://social.msdn.microsoft.com/Forums/windows/en-US/e61f12f7-ee36-4a4e-8242-185cfcb644cb/is-there-a-3d-on-a-horizon-for-winforms-?forum=winformsdesigner // You can expect continued support for WinForms, but do not expect anything new to come from Microsoft. // They seem to be pushing toward a UI that works will with Desktop and Web applications. /// <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(IApp page) { var size = 600; var gl = new WebGLRenderingContext(); var canvas = gl.canvas.AttachToDocument(); Native.document.body.style.overflow = IStyle.OverflowEnum.hidden; canvas.style.SetLocation(0, 0, size, size); canvas.width = size; canvas.height = size; var gl_viewportWidth = size; var gl_viewportHeight = size; var shaderProgram = gl.createProgram( new GeometryVertexShader(), new GeometryFragmentShader() ); gl.linkProgram(shaderProgram); gl.useProgram(shaderProgram); var shaderProgram_vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); gl.enableVertexAttribArray((uint)shaderProgram_vertexPositionAttribute); // new in lesson 02 var shaderProgram_vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor"); gl.enableVertexAttribArray((uint)shaderProgram_vertexColorAttribute); var shaderProgram_pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); var shaderProgram_mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); var mvMatrix = glMatrix.mat4.create(); var mvMatrixStack = new Stack<Float32Array>(); var pMatrix = glMatrix.mat4.create(); #region new in lesson 03 Action mvPushMatrix = delegate { var copy = glMatrix.mat4.create(); glMatrix.mat4.set(mvMatrix, copy); mvMatrixStack.Push(copy); }; Action mvPopMatrix = delegate { mvMatrix = mvMatrixStack.Pop(); }; #endregion #region setMatrixUniforms Action setMatrixUniforms = delegate { gl.uniformMatrix4fv(shaderProgram_pMatrixUniform, false, pMatrix); gl.uniformMatrix4fv(shaderProgram_mvMatrixUniform, false, mvMatrix); }; #endregion #region init buffers #region cube var cubeVertexPositionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); var cubesize = 1.0f * 0.05f; var vertices = new[]{ // Front face -cubesize, -cubesize, cubesize, cubesize, -cubesize, cubesize, cubesize, cubesize, cubesize, -cubesize, cubesize, cubesize, // Back face -cubesize, -cubesize, -cubesize, -cubesize, cubesize, -cubesize, cubesize, cubesize, -cubesize, cubesize, -cubesize, -cubesize, // Top face -cubesize, cubesize, -cubesize, -cubesize, cubesize, cubesize, cubesize, cubesize, cubesize, cubesize, cubesize, -cubesize, // Bottom face -cubesize, -cubesize, -cubesize, cubesize, -cubesize, -cubesize, cubesize, -cubesize, cubesize, -cubesize, -cubesize, cubesize, // Right face cubesize, -cubesize, -cubesize, cubesize, cubesize, -cubesize, cubesize, cubesize, cubesize, cubesize, -cubesize, cubesize, // Left face -cubesize, -cubesize, -cubesize, -cubesize, -cubesize, cubesize, -cubesize, cubesize, cubesize, -cubesize, cubesize, -cubesize }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); var cubeVertexPositionBuffer_itemSize = 3; var cubeVertexPositionBuffer_numItems = 6 * 6; var squareVertexColorBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexColorBuffer); // 216, 191, 18 var colors = new[]{ 1.0f, 0.6f, 0.0f, 1.0f, // Front face 1.0f, 0.6f, 0.0f, 1.0f, // Front face 1.0f, 0.6f, 0.0f, 1.0f, // Front face 1.0f, 0.6f, 0.0f, 1.0f, // Front face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Left face 1.0f, 0.8f, 0.0f, 1.0f, // Left face 1.0f, 0.8f, 0.0f, 1.0f, // Left face 1.0f, 0.8f, 0.0f, 1.0f // Left face }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW); var cubeVertexColorBuffer_itemSize = 4; var cubeVertexColorBuffer_numItems = 24; var cubeVertexIndexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); var cubeVertexIndices = new UInt16[]{ 0, 1, 2, 0, 2, 3, // Front face 4, 5, 6, 4, 6, 7, // Back face 8, 9, 10, 8, 10, 11, // Top face 12, 13, 14, 12, 14, 15, // Bottom face 16, 17, 18, 16, 18, 19, // Right face 20, 21, 22, 20, 22, 23 // Left face }; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW); var cubeVertexIndexBuffer_itemSize = 1; var cubeVertexIndexBuffer_numItems = 36; #endregion #endregion gl.clearColor(0.0f, 0.0f, 0.0f, alpha: 1.0f); gl.enable(gl.DEPTH_TEST); var rWindDelta = 0.0f; var rCubeDelta = 1.0f; #region animate var rCube = 0f; var rWind = 0f; var lastTime = 0L; Action animate = delegate { var timeNow = new IDate().getTime(); if (lastTime != 0) { var elapsed = timeNow - lastTime; rCube -= ((75 * elapsed) / 1000.0f) * rCubeDelta; rWind -= ((75 * elapsed) / 1000.0f) * rWindDelta; } lastTime = timeNow; }; #endregion #region degToRad Func<float, float> degToRad = (degrees) => { return degrees * (f)Math.PI / 180f; }; #endregion 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 += e => { Native.document.exitPointerLock(); }; var syncdata = new ApplicationWebService[0]; //this.x = 0; this.y = 0; var st = new Stopwatch(); st.Start(); xml = new XElement( "hi", new XAttribute("a", "can you see me?") ); Action sync = async delegate { while (true) { var local_syncdata = await onsyncframe(); onsyncframe_ElapsedMilliseconds = st.ElapsedMilliseconds; st.Restart(); syncframe++; Console.WriteLine(new { syncframe, local_syncdata.Length }); syncdata = local_syncdata; } }; sync(); #region drawScene Action drawScene = delegate { gl.viewport(0, 0, gl_viewportWidth, gl_viewportHeight); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); glMatrix.mat4.perspective(45f, (float)gl_viewportWidth / (float)gl_viewportHeight, 0.1f, 100.0f, pMatrix); glMatrix.mat4.identity(mvMatrix); glMatrix.mat4.translate(mvMatrix, new float[] { 0f, 0.0f, -7.0f }); mvPushMatrix(); glMatrix.mat4.rotate(mvMatrix, degToRad(rWind), new float[] { 0f, 1f, 0f }); glMatrix.mat4.rotate(mvMatrix, __pointer_y * 0.01f, new float[] { 1f, 0, 0f }); glMatrix.mat4.rotate(mvMatrix, __pointer_x * 0.01f, new float[] { 0, 1f, 0f }); #region DrawFrameworkWingAtX Action<float, float> DrawFrameworkWingAtX = (WingX, WingY) => { #region draw center cube mvPushMatrix(); glMatrix.mat4.translate(mvMatrix, new float[] { cubesize * WingX, cubesize * WingY, 0 }); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, cubeVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexColorBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); setMatrixUniforms(); gl.drawElements(gl.TRIANGLES, cubeVertexPositionBuffer_numItems, gl.UNSIGNED_SHORT, 0); mvPopMatrix(); #endregion }; #endregion foreach (var item in syncdata) { DrawFrameworkWingAtX(item.x, item.y); } mvPopMatrix(); #region draw cube on the right to remind where we started glMatrix.mat4.translate(mvMatrix, new float[] { (3.0f).ToInteractiveFloatDataGridView(), (2.0f).ToInteractiveFloatDataGridView(), (0.0f).ToInteractiveFloatDataGridView() }); mvPushMatrix(); glMatrix.mat4.rotate(mvMatrix, degToRad(rCube), new float[] { 1f, 1f, 1f }); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, cubeVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexColorBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); setMatrixUniforms(); gl.drawElements(gl.TRIANGLES, cubeVertexPositionBuffer_numItems, gl.UNSIGNED_SHORT, 0); mvPopMatrix(); #endregion }; drawScene(); #endregion #region AtResize Action AtResize = delegate { gl_viewportWidth = Native.window.Width; gl_viewportHeight = Native.window.Height; canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportHeight); canvas.width = gl_viewportWidth; canvas.height = gl_viewportHeight; }; Native.window.onresize += e => { AtResize(); }; AtResize(); #endregion #region tick Native.window.onframe += delegate { c++; Native.Document.title = new { c, syncframe }.ToString(); drawScene(); animate(); }; #endregion }
/// <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) { // http://hiddenlighthouse.wordpress.com/2012/12/07/star-tetrahedron-the-star-of-david-3/ var size = 96; var canvas = gl.canvas; if (page != null) canvas.AttachToDocument(); canvas.width = size; canvas.height = size; var gl_viewportWidth = size; var gl_viewportHeight = size; #region IsDisposed var IsDisposed = false; this.Dispose = delegate { if (IsDisposed) return; IsDisposed = true; canvas.Orphanize(); }; #endregion #region AtResize if (page == null) { Console.WriteLine("page is null"); } else { Console.WriteLine("got page"); Native.document.body.style.overflow = IStyle.OverflowEnum.hidden; canvas.style.SetLocation(0, 0, size, size); Action AtResize = delegate { gl_viewportWidth = Native.window.Width; gl_viewportHeight = Native.window.Height; canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportHeight); canvas.width = gl_viewportWidth; canvas.height = gl_viewportHeight; }; Native.window.onresize += e => { AtResize(); }; AtResize(); } #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 #region initShaders var shaderProgram = gl.createProgram( new GeometryVertexShader(), new GeometryFragmentShader() ); gl.linkProgram(shaderProgram); gl.useProgram(shaderProgram); var shaderProgram_vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); gl.enableVertexAttribArray((uint)shaderProgram_vertexPositionAttribute); // new in lesson 02 var shaderProgram_vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor"); gl.enableVertexAttribArray((uint)shaderProgram_vertexColorAttribute); var shaderProgram_pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); var shaderProgram_mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); #endregion var mvMatrix = glMatrix.mat4.create(); var mvMatrixStack = new Stack<Float32Array>(); var pMatrix = glMatrix.mat4.create(); Action mvPushMatrix = delegate { var copy = glMatrix.mat4.create(); glMatrix.mat4.set(mvMatrix, copy); mvMatrixStack.Push(copy); }; Action mvPopMatrix = delegate { mvMatrix = mvMatrixStack.Pop(); }; #region setMatrixUniforms Action setMatrixUniforms = delegate { gl.uniformMatrix4fv(shaderProgram_pMatrixUniform, false, pMatrix); gl.uniformMatrix4fv(shaderProgram_mvMatrixUniform, false, mvMatrix); }; #endregion #region init buffers #region pyramid var pyramidVertexPositionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, pyramidVertexPositionBuffer); var vertices = new[]{ // Front face 0.0f, 1.0f, 0.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, // Right face 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, // Back face 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, // Left face 0.0f, 1.0f, 0.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); var pyramidVertexPositionBuffer_itemSize = 3; var pyramidVertexPositionBuffer_numItems = 12; var pyramidVertexColorBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, pyramidVertexColorBuffer); var colors = new[]{ // Front face 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // Right face 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, // Back face 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // Left face 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW); var pyramidVertexColorBuffer_itemSize = 4; var pyramidVertexColorBuffer_numItems = 12; #endregion #region cube var cubeVertexPositionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); vertices = new[]{ // Front face RED -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, // Back face YELLOW -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, // Top face GREEN -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, // Bottom face BEIGE -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, // Right face PURPLE 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, // Left face BLUE -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); var cubeVertexPositionBuffer_itemSize = 3; var cubeVertexPositionBuffer_numItems = 6 * 6; var cubeVertexColorBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer); colors = new[]{ // RED 1.0f, 0.0f, 0.0f, 1.0f, // Front face 1.0f, 0.0f, 0.0f, 1.0f, // Front face 1.0f, 0.0f, 0.0f, 1.0f, // Front face 1.0f, 0.0f, 0.0f, 1.0f, // Front face // YELLOW 1.0f, 1.0f, 0.0f, 1.0f, // Back face 1.0f, 1.0f, 0.0f, 1.0f, // Back face 1.0f, 1.0f, 0.0f, 1.0f, // Back face 1.0f, 1.0f, 0.0f, 1.0f, // Back face // GREEN 0.0f, 1.0f, 0.0f, 1.0f, // Top face 0.0f, 1.0f, 0.0f, 1.0f, // Top face 0.0f, 1.0f, 0.0f, 1.0f, // Top face 0.0f, 1.0f, 0.0f, 1.0f, // Top face 1.0f, 0.5f, 0.5f, 1.0f, // Bottom face 1.0f, 0.5f, 0.5f, 1.0f, // Bottom face 1.0f, 0.5f, 0.5f, 1.0f, // Bottom face 1.0f, 0.5f, 0.5f, 1.0f, // Bottom face 1.0f, 0.0f, 1.0f, 1.0f, // Right face 1.0f, 0.0f, 1.0f, 1.0f, // Right face 1.0f, 0.0f, 1.0f, 1.0f, // Right face 1.0f, 0.0f, 1.0f, 1.0f, // Right face 0.0f, 0.0f, 1.0f, 1.0f, // Left face 0.0f, 0.0f, 1.0f, 1.0f, // Left face 0.0f, 0.0f, 1.0f, 1.0f, // Left face 0.0f, 0.0f, 1.0f, 1.0f // Left face }; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW); var cubeVertexColorBuffer_itemSize = 4; var cubeVertexColorBuffer_numItems = 24; var cubeVertexIndexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); var cubeVertexIndices = new UInt16[]{ 0, 1, 2, 0, 2, 3, // Front face 4, 5, 6, 4, 6, 7, // Back face 8, 9, 10, 8, 10, 11, // Top face 12, 13, 14, 12, 14, 15, // Bottom face 16, 17, 18, 16, 18, 19, // Right face 20, 21, 22, 20, 22, 23 // Left face }; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW); var cubeVertexIndexBuffer_itemSize = 1; var cubeVertexIndexBuffer_numItems = cubeVertexPositionBuffer_numItems; #endregion #endregion gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); gl.enable(gl.DEPTH_TEST); #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 rPyramid = 0f; var rCube = 0f; var lastTime = 0L; Action animate = delegate { var timeNow = new IDate().getTime(); if (lastTime != 0) { var elapsed = timeNow - lastTime; rPyramid += (90 * elapsed) / 1000.0f; rCube -= (75 * elapsed) / 1000.0f; } lastTime = timeNow; }; Func<float, float> degToRad = (degrees) => { return degrees * (f)Math.PI / 180f; }; #region drawScene Action drawScene = delegate { gl.viewport(0, 0, gl_viewportWidth, gl_viewportHeight); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); glMatrix.mat4.perspective(45f, (float)gl_viewportWidth / (float)gl_viewportHeight, 0.1f, 100.0f, pMatrix); glMatrix.mat4.identity(mvMatrix); mvPushMatrix(); glMatrix.mat4.translate(mvMatrix, new float[] { 0f, 0.5f, -7.0f }); //glMatrix.mat4.rotate(mvMatrix, (f)Math.PI, new float[] { 0f, 0f, 1f }); glMatrix.mat4.rotate(mvMatrix, __pointer_y * 0.01f, new float[] { 1f, 0, 0f }); glMatrix.mat4.rotate(mvMatrix, __pointer_x * 0.01f, new float[] { 0, 1f, 0f }); glMatrix.mat4.rotate(mvMatrix, degToRad(rPyramid), new float[] { 0f, 1f, 0f }); gl.bindBuffer(gl.ARRAY_BUFFER, pyramidVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, pyramidVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, pyramidVertexColorBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, pyramidVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); setMatrixUniforms(); gl.drawArrays(gl.TRIANGLES, 0, pyramidVertexPositionBuffer_numItems); mvPopMatrix(); mvPushMatrix(); glMatrix.mat4.translate(mvMatrix, new float[] { 0f, -0.5f, -7.0f }); glMatrix.mat4.rotate(mvMatrix, __pointer_y * 0.01f, new float[] { 1f, 0, 0f }); glMatrix.mat4.rotate(mvMatrix, __pointer_x * 0.01f, new float[] { 0, 1f, 0f }); glMatrix.mat4.rotate(mvMatrix, (f)Math.PI, new float[] { 0f, 0f, 1f }); glMatrix.mat4.rotate(mvMatrix, degToRad(rPyramid), new float[] { 0f, 1f, 0f }); gl.bindBuffer(gl.ARRAY_BUFFER, pyramidVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, pyramidVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, pyramidVertexColorBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, pyramidVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); setMatrixUniforms(); gl.drawArrays(gl.TRIANGLES, 0, pyramidVertexPositionBuffer_numItems); mvPopMatrix(); //glMatrix.mat4.translate(mvMatrix, new float[] { 3.0f, 0.0f, 0.0f }); //#region new in lesson 04 //mvPushMatrix(); //glMatrix.mat4.rotate(mvMatrix, degToRad(rCube), new float[] { 1f, 1f, 1f }); //#endregion //gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); //gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, cubeVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); //gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer); //gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); //gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); //setMatrixUniforms(); //gl.drawElements(gl.TRIANGLES, cubeVertexIndexBuffer_numItems, gl.UNSIGNED_SHORT, 0); //#region new in lesson 03 //mvPopMatrix(); //#endregion }; drawScene(); #endregion var c = 0; Native.window.onframe += delegate { c++; Native.Document.title = "" + c; drawScene(); animate(); }; }