Exemple #1
0
        private void InitializeContent(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


            var canvas = new IHTMLCanvas().AttachToDocument();

            Native.Document.body.style.overflow = IStyle.OverflowEnum.hidden;

            canvas.style.SetLocation(0, 0);


            //http://www.khronos.org/webgl/public-mailing-list/archives/1002/msg00125.html


            var gl = (WebGLRenderingContext)canvas.getContext("experimental-webgl");

            #region Dispose
            var IsDisposed = false;

            Dispose = delegate
            {
                if (IsDisposed)
                {
                    return;
                }

                IsDisposed = true;

                canvas.Orphanize();
            };
            #endregion


            var s = new PulsSurface(this);

            this.onsurface(gl);

            #region AtResize
            Action AtResize = delegate
            {
                if (IsDisposed)
                {
                    return;
                }

                canvas.width  = Native.window.Width;
                canvas.height = Native.window.Height;

                this.onresize(Native.window.Width, Native.window.Height);

                Console.WriteLine("onresize");
            };

            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



            #region loop
            Action loop = null;

            loop = delegate
            {
                if (IsDisposed)
                {
                    return;
                }

                this.onframe();

                Native.window.requestAnimationFrame += loop;
            };

            Native.window.requestAnimationFrame += loop;
            #endregion
        }
Exemple #2
0
        void InitializeContent(IDefault page = null)
        {
            var vertices = new List <float>();
            var indices  = new List <ushort>();
            var colors   = new List <float>();
            var uvs      = new List <float>();

            var radius        = 7;
            var currentRadius = radius;
            var segments      = (ushort)24;
            var spacing       = 2;
            var numRings      = 18;
            var index         = (ushort)0;
            var currentTime   = 0.0f;



            #region generateGeometry
            Action generateGeometry = delegate
            {
                for (var ring = 0; ring < numRings; ring++)
                {
                    for (var segment = 0; segment < segments; segment++)
                    {
                        var degrees = (360 / segments) * segment;
                        var radians = (Math.PI / 180) * degrees;
                        var x       = (float)Math.Cos(radians) * currentRadius;
                        var y       = (float)Math.Sin(radians) * currentRadius;
                        var z       = ring * -spacing;

                        vertices.Add(x, y, z);

                        if (segment < (segments - 1) / 2)
                        {
                            uvs.Add((1.0f / (segments)) * segment * 2, (1.0f / 4) * ring);
                        }
                        else
                        {
                            uvs.Add(2.0f - ((1.0f / (segments)) * segment * 2), (1.0f / 4) * ring);
                        }

                        var color = 1.0f - ((1.0f / (numRings - 1)) * ring);
                        colors.Add(color, color, color, 1.0f);

                        if (ring < numRings - 1)
                        {
                            if (segment < segments - 1)
                            {
                                indices.Add(index, (ushort)(index + segments + 1), (ushort)(index + segments));
                                indices.Add(index, (ushort)(index + 1), (ushort)(index + segments + 1));
                            }
                            else
                            {
                                indices.Add(index, (ushort)(index + 1), (ushort)(index + segments));
                                indices.Add(index, (ushort)(index - segments + 1), (ushort)(index + 1));
                            }
                        }

                        index++;
                    }
                    currentRadius -= radius / numRings;
                }
            };


            generateGeometry();
            #endregion


            var size = 500;

            var gl_viewportWidth  = size;
            var gl_viewportHeight = size;


            #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

            #region drawingMode
            var drawingMode = gl.TRIANGLES;

            page.With(
                delegate
            {
                page.triangles.onchange +=
                    delegate
                {
                    if (drawingMode == gl.TRIANGLES)
                    {
                        drawingMode = gl.LINE_STRIP;
                    }
                    else
                    {
                        drawingMode = gl.TRIANGLES;
                    }
                };
            }
                );
            #endregion

            var shaderProgram = gl.createProgram(
                new TunnelVertexShader(),
                new TunnelFragmentShader()
                );

            // "WebGL: INVALID_OPERATION: drawElements: attribs not setup correctly", source: http://192.168.43.252:16876/ (0)
            // I/chromium( 3770): [INFO:CONSOLE(0)] "WebGL: INVALID_OPERATION: useProgram: program not valid", source: http://192.168.43.252:16876/ (0)



            gl.linkProgram(shaderProgram);
            gl.useProgram(shaderProgram);

            var shaderProgram_vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
            gl.enableVertexAttribArray((uint)shaderProgram_vertexPositionAttribute);

            var shaderProgram_vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor");
            gl.enableVertexAttribArray((uint)shaderProgram_vertexColorAttribute);

            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");
            var shaderProgram_fTimeUniform    = gl.getUniformLocation(shaderProgram, "fTime");
            var shaderProgram_samplerUniform  = gl.getUniformLocation(shaderProgram, "uSampler");



            var mvMatrix      = default(Matrix);
            var mvMatrixStack = new Stack <Matrix>();
            var pMatrix       = default(Matrix);

            Action mvPopMatrix = delegate
            {
                mvMatrix = mvMatrixStack.Pop();
            };

            // http://prototypejs.org/api/array/flatten
            Action setMatrixUniforms =
                delegate
            {
                gl.uniformMatrix4fv(shaderProgram_pMatrixUniform, false, new Float32Array(pMatrix.flatten()));
                gl.uniformMatrix4fv(shaderProgram_mvMatrixUniform, false, new Float32Array(mvMatrix.flatten()));
            };


            Action mvPushMatrix = delegate
            {
                mvMatrixStack.Push(mvMatrix.dup());
            };



            Action loadIdentity = delegate
            {
                mvMatrix = __sylvester.Matrix.I(4);
            };


            Action <Matrix> multMatrix = (m) =>
            {
                mvMatrix = mvMatrix.x(m);
            };

            Action <float[]> mvTranslate = (v) =>
            {
                var m = __sylvester.Matrix.Translation(__sylvester.Vector.create(new[] { v[0], v[1], v[2] })).ensure4x4();
                multMatrix(m);
            };


            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 <float, float, float, float> perspective = (fovy, aspect, znear, zfar) =>
            {
                pMatrix = __glUtils.globals.makePerspective(fovy, aspect, znear, zfar);
            };



            #region IsDisposed
            var IsDisposed = false;

            Dispose = delegate
            {
                if (IsDisposed)
                {
                    return;
                }

                IsDisposed = true;

                canvas.Orphanize();
            };
            #endregion


            new HTML.Images.FromAssets.texture().InvokeOnComplete(
                (texture_image) =>
            {
                #region initTexture
                var texture = gl.createTexture();

                gl.bindTexture(gl.TEXTURE_2D, texture);
                gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 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.NEAREST);
                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, (int)gl.NEAREST);
                gl.bindTexture(gl.TEXTURE_2D, null);
                #endregion


                #region initBuffers
                var cubeVertexPositionBuffer = gl.createBuffer();
                gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer);
                gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices.ToArray()), gl.STATIC_DRAW);
                var cubeVertexPositionBuffer_itemSize = 3;
                var cubeVertexPositionBuffer_numItems = vertices.Count / 3;

                var cubeVertexColorBuffer = gl.createBuffer();
                gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer);

                gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors.ToArray()), gl.STATIC_DRAW);
                var cubeVertexColorBuffer_itemSize = 4;
                var cubeVertexColorBuffer_numItems = colors.Count / 4;

                var cubeVertexIndexBuffer = gl.createBuffer();
                gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer);
                gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices.ToArray()), gl.STATIC_DRAW);
                var cubeVertexIndexBuffer_itemSize = 1;
                var cubeVertexIndexBuffer_numItems = indices.Count;

                var cubeVertexTextureCoordBuffer = gl.createBuffer();
                gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexTextureCoordBuffer);
                gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(uvs.ToArray()), gl.STATIC_DRAW);
                var cubeVertexTextureCoordBuffer_itemSize = 2;
                var cubeVertexTextureCoordBuffer_numItems = uvs.Count / 2;
                #endregion


                gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);

                gl.clearDepth(1.0f);

                gl.enable(gl.DEPTH_TEST);
                gl.depthFunc(gl.LEQUAL);



                Action AtResize = delegate
                {
                    gl_viewportWidth  = Convert.ToInt32(Native.window.Width * zoom);
                    gl_viewportHeight = Convert.ToInt32(Native.window.Height * zoom);

                    canvas.style.SetLocation(0, 0, Native.window.Width, Native.window.Height);

                    canvas.width  = Convert.ToInt32(Native.window.Width * zoom);
                    canvas.height = Convert.ToInt32(Native.window.Height * zoom);
                };

                #region onresize
                Native.window.onresize +=
                    delegate
                {
                    AtResize();
                };
                #endregion

                AtResize();


                var rCube = 0;

                #region drawScene

                Native.window.onframe += delegate
                {
                    if (IsDisposed)
                    {
                        return;
                    }

                    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);
                    loadIdentity();

                    mvTranslate(new[] { 0.0f, 0.0f, -8.0f });

                    mvPushMatrix();
                    mvRotate(rCube, new[] { 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, cubeVertexColorBuffer);
                    gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_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, texture);
                    gl.uniform1i(shaderProgram_samplerUniform, 0);

                    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer);
                    setMatrixUniforms();

                    // ?
                    //  a[0].CS___8__locals19.currentTime = (((a[0].CS___8__locals19.currentTime + 0.01)) >>> 0);
                    // haha. wtf jsc. :)
                    currentTime = (currentTime + 0.01f);

                    Native.document.title = new { currentTime }.ToString();

                    gl.uniform1f(shaderProgram_fTimeUniform, currentTime);
                    gl.drawElements(drawingMode, cubeVertexIndexBuffer_numItems, gl.UNSIGNED_SHORT, 0);

                    mvPopMatrix();
                };

                #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
            }
                );
        }
Exemple #3
0
        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
        }
        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

        }
        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 vertices = new List<float>();
            var indices = new List<ushort>();
            var colors = new List<float>();
            var uvs = new List<float>();

            var radius = 7;
            var currentRadius = radius;
            var segments = (ushort)24;
            var spacing = 2;
            var numRings = 18;
            var index = (ushort)0;
            var currentTime = 0.0f;




            #region generateGeometry
            Action generateGeometry = delegate
            {
                for (var ring = 0; ring < numRings; ring++)
                {
                    for (var segment = 0; segment < segments; segment++)
                    {
                        var degrees = (360 / segments) * segment;
                        var radians = (Math.PI / 180) * degrees;
                        var x = (float)Math.Cos(radians) * currentRadius;
                        var y = (float)Math.Sin(radians) * currentRadius;
                        var z = ring * -spacing;

                        vertices.Add(x, y, z);

                        if (segment < (segments - 1) / 2)
                        {
                            uvs.Add((1.0f / (segments)) * segment * 2, (1.0f / 4) * ring);
                        }
                        else
                        {
                            uvs.Add(2.0f - ((1.0f / (segments)) * segment * 2), (1.0f / 4) * ring);
                        }

                        var color = 1.0f - ((1.0f / (numRings - 1)) * ring);
                        colors.Add(color, color, color, 1.0f);

                        if (ring < numRings - 1)
                        {
                            if (segment < segments - 1)
                            {
                                indices.Add(index, (ushort)(index + segments + 1), (ushort)(index + segments));
                                indices.Add(index, (ushort)(index + 1), (ushort)(index + segments + 1));
                            }
                            else
                            {
                                indices.Add(index, (ushort)(index + 1), (ushort)(index + segments));
                                indices.Add(index, (ushort)(index - segments + 1), (ushort)(index + 1));
                            }
                        }

                        index++;
                    }
                    currentRadius -= radius / numRings;
                }
            };


            generateGeometry();
            #endregion


            var size = 500;

            var gl_viewportWidth = size;
            var gl_viewportHeight = size;


            #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

            #region drawingMode
            var drawingMode = gl.TRIANGLES;

            page.With(
                delegate
                {
                    page.triangles.onchange +=
                        delegate
                        {
                            if (drawingMode == gl.TRIANGLES)
                                drawingMode = gl.LINE_STRIP;
                            else
                                drawingMode = gl.TRIANGLES;
                        };
                }
            );
            #endregion

            var shaderProgram = gl.createProgram(
                new TunnelVertexShader(),
                new TunnelFragmentShader()
                );

            // "WebGL: INVALID_OPERATION: drawElements: attribs not setup correctly", source: http://192.168.43.252:16876/ (0)
            // I/chromium( 3770): [INFO:CONSOLE(0)] "WebGL: INVALID_OPERATION: useProgram: program not valid", source: http://192.168.43.252:16876/ (0)





            gl.linkProgram(shaderProgram);
            gl.useProgram(shaderProgram);

            var shaderProgram_vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
            gl.enableVertexAttribArray((uint)shaderProgram_vertexPositionAttribute);

            var shaderProgram_vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor");
            gl.enableVertexAttribArray((uint)shaderProgram_vertexColorAttribute);

            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");
            var shaderProgram_fTimeUniform = gl.getUniformLocation(shaderProgram, "fTime");
            var shaderProgram_samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler");



            var mvMatrix = default(Matrix);
            var mvMatrixStack = new Stack<Matrix>();
            var pMatrix = default(Matrix);

            Action mvPopMatrix = delegate
           {
               mvMatrix = mvMatrixStack.Pop();
           };

            // http://prototypejs.org/api/array/flatten
            Action setMatrixUniforms =
                delegate
                {
                    gl.uniformMatrix4fv(shaderProgram_pMatrixUniform, false, new Float32Array(pMatrix.flatten()));
                    gl.uniformMatrix4fv(shaderProgram_mvMatrixUniform, false, new Float32Array(mvMatrix.flatten()));
                };


            Action mvPushMatrix = delegate
            {
                mvMatrixStack.Push(mvMatrix.dup());
            };



            Action loadIdentity = delegate
            {
                mvMatrix = __sylvester.Matrix.I(4);
            };


            Action<Matrix> multMatrix = (m) =>
            {
                mvMatrix = mvMatrix.x(m);
            };

            Action<float[]> mvTranslate = (v) =>
            {
                var m = __sylvester.Matrix.Translation(__sylvester.Vector.create(new[] { v[0], v[1], v[2] })).ensure4x4();
                multMatrix(m);
            };


            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<float, float, float, float> perspective = (fovy, aspect, znear, zfar) =>
            {
                pMatrix = __glUtils.globals.makePerspective(fovy, aspect, znear, zfar);
            };



            #region IsDisposed
            var IsDisposed = false;

            Dispose = delegate
            {
                if (IsDisposed)
                    return;

                IsDisposed = true;

                canvas.Orphanize();
            };
            #endregion


            new HTML.Images.FromAssets.texture().InvokeOnComplete(
                (texture_image) =>
                {
                    #region initTexture
                    var texture = gl.createTexture();

                    gl.bindTexture(gl.TEXTURE_2D, texture);
                    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 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.NEAREST);
                    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, (int)gl.NEAREST);
                    gl.bindTexture(gl.TEXTURE_2D, null);
                    #endregion


                    #region initBuffers
                    var cubeVertexPositionBuffer = gl.createBuffer();
                    gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer);
                    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices.ToArray()), gl.STATIC_DRAW);
                    var cubeVertexPositionBuffer_itemSize = 3;
                    var cubeVertexPositionBuffer_numItems = vertices.Count / 3;

                    var cubeVertexColorBuffer = gl.createBuffer();
                    gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer);

                    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors.ToArray()), gl.STATIC_DRAW);
                    var cubeVertexColorBuffer_itemSize = 4;
                    var cubeVertexColorBuffer_numItems = colors.Count / 4;

                    var cubeVertexIndexBuffer = gl.createBuffer();
                    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer);
                    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices.ToArray()), gl.STATIC_DRAW);
                    var cubeVertexIndexBuffer_itemSize = 1;
                    var cubeVertexIndexBuffer_numItems = indices.Count;

                    var cubeVertexTextureCoordBuffer = gl.createBuffer();
                    gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexTextureCoordBuffer);
                    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(uvs.ToArray()), gl.STATIC_DRAW);
                    var cubeVertexTextureCoordBuffer_itemSize = 2;
                    var cubeVertexTextureCoordBuffer_numItems = uvs.Count / 2;
                    #endregion


                    gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);

                    gl.clearDepth(1.0f);

                    gl.enable(gl.DEPTH_TEST);
                    gl.depthFunc(gl.LEQUAL);




                    Action AtResize = delegate
                    {

                        gl_viewportWidth = Convert.ToInt32(Native.window.Width * zoom);
                        gl_viewportHeight = Convert.ToInt32(Native.window.Height * zoom);

                        canvas.style.SetLocation(0, 0, Native.window.Width, Native.window.Height);

                        canvas.width = Convert.ToInt32(Native.window.Width * zoom);
                        canvas.height = Convert.ToInt32(Native.window.Height * zoom);
                    };

                    #region onresize
                    Native.window.onresize +=
                        delegate
                        {
                            AtResize();
                        };
                    #endregion

                    AtResize();


                    var rCube = 0;

                    #region drawScene

                    Native.window.onframe += delegate
                    {
                        if (IsDisposed)
                            return;

                        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);
                        loadIdentity();

                        mvTranslate(new[] { 0.0f, 0.0f, -8.0f });

                        mvPushMatrix();
                        mvRotate(rCube, new[] { 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, cubeVertexColorBuffer);
                        gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_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, texture);
                        gl.uniform1i(shaderProgram_samplerUniform, 0);

                        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer);
                        setMatrixUniforms();

                        // ?
                        //  a[0].CS___8__locals19.currentTime = (((a[0].CS___8__locals19.currentTime + 0.01)) >>> 0);
                        // haha. wtf jsc. :)
                        currentTime = (currentTime + 0.01f);

                        Native.document.title = new { currentTime }.ToString();

                        gl.uniform1f(shaderProgram_fTimeUniform, currentTime);
                        gl.drawElements(drawingMode, cubeVertexIndexBuffer_numItems, gl.UNSIGNED_SHORT, 0);

                        mvPopMatrix();

                    };

                    #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
                }
            );





        }
Exemple #7
0
        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();
                    };
                }
                    );
            }
                );
        }
    }
        private void InitializeContent(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


			var canvas = new IHTMLCanvas().AttachToDocument();

            Native.Document.body.style.overflow = IStyle.OverflowEnum.hidden;

            canvas.style.SetLocation(0, 0);


            //http://www.khronos.org/webgl/public-mailing-list/archives/1002/msg00125.html


            var gl = (WebGLRenderingContext)canvas.getContext("experimental-webgl");

            #region Dispose
            var IsDisposed = false;

            Dispose = delegate
            {
                if (IsDisposed)
                    return;

                IsDisposed = true;

                canvas.Orphanize();
            };
            #endregion


            var s = new PulsSurface(this);

            this.onsurface(gl);

            #region AtResize
            Action AtResize = delegate
            {
                if (IsDisposed)
                {
                    return;
                }

                canvas.width = Native.window.Width;
                canvas.height = Native.window.Height;

                this.onresize(Native.window.Width, Native.window.Height);

                Console.WriteLine("onresize");
            };

            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




            #region loop
            Action loop = null;

            loop = delegate
            {
                if (IsDisposed)
                    return;

                this.onframe();

                Native.window.requestAnimationFrame += loop;

            };

            Native.window.requestAnimationFrame += loop;
            #endregion


        }