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