public static WebGLBuffer createQuadVBO(gl gl , float left = -1.0f // y reversed? , float bottom = -1.0f , float right = 1.0f , float top = 1.0f ) { // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2015/201503/20150311 //enter createQuadVBO { { i = 0, value = null } } //enter createQuadVBO { { i = 1, value = null } } //enter createQuadVBO { { i = 2, value = 1 } } //enter createQuadVBO { { i = 3, value = null } } //enter createQuadVBO { { i = 4, value = null } } //enter createQuadVBO { { i = 5, value = null } } //enter createQuadVBO { { i = 6, value = 1 } } //enter createQuadVBO { { i = 7, value = null } } //enter createQuadVBO { { i = 8, value = 1 } } //enter createQuadVBO { { i = 9, value = null } } //enter createQuadVBO { { i = 10, value = null } } //enter createQuadVBO { { i = 11, value = null } } var fvertices = new float[] { // left top left, bottom, // right top //right, -1.0f, right, bottom, // left bottom left, top, // right top //right, -1.0f, right, bottom, // right bottom //right, 1.0f, right, top, // left bottom left,top }; //new IHTMLPre { "enter createQuadVBO" }.AttachToDocument(); //for (int i = 0; i < fvertices.Length; i++) //{ // var value = fvertices[i]; // new IHTMLPre { "enter createQuadVBO " + new { i, value } }.AttachToDocument(); //} // new Buffer? var vbo = new WebGLBuffer(gl); //var vbo = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, vbo); var vertices = new Float32Array(fvertices); gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); gl.bindBuffer(gl.ARRAY_BUFFER, null); return vbo; }
public Effect( AudioContext ac, WebGLRenderingContext gl, RefreshTexturThumbailDelegate callback, object obj, bool forceMuted, bool forcePaused) { //new IHTMLPre { "enter Effect" }.AttachToDocument(); var ext = gl.getExtension("OES_standard_derivatives"); var supportsDerivatives = (ext != null); //if (supportsDerivatives) gl.hint(ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES, gl.NICEST); var ext2 = gl.getExtension("OES_texture_float"); this.mSupportTextureFloat = (ext2 != null); var precision = DetermineShaderPrecission(gl); //this.mGainNode = ac.createGain(); //this.mGainNode.connect(ac.destination); this.mQuadVBO = createQuadVBO(gl); this.mPasses = new EffectPass[2]; for (var i = 0; i < 2; i++) { this.mPasses[i] = new EffectPass( ac, gl, precision, supportsDerivatives, callback, obj, forceMuted, forcePaused, this.mQuadVBO, this.mGainNode ); } }
// X:\jsc.svn\examples\glsl\future\GLSLShaderToyPip\GLSLShaderToyPip\Application.cs public EffectPass( AudioContext wa = null, gl gl = null, string precission = null, bool supportDerivatives = false, RefreshTexturThumbailDelegate callback = null, object obj = null, bool forceMuted = false, bool forcePaused = false, // createQuadVBO // ARRAY_BUFFER WebGLBuffer quadVBO = null, GainNode outputGainNode = null ) { //new IHTMLPre { "enter EffectPass" }.AttachToDocument(); // used by? var mFrame = 0; this.MakeHeader_Image = delegate { #region MakeHeader_Image //new IHTMLPre { "enter MakeHeader_Image" }.AttachToDocument(); var header = precission; var headerlength = 3; if (supportDerivatives) { header += "#extension GL_OES_standard_derivatives : enable\n"; headerlength++; } header += "uniform vec3 iResolution;\n" + "uniform float iGlobalTime;\n" + "uniform float iChannelTime[4];\n" + "uniform vec4 iMouse;\n" + "uniform vec4 iDate;\n" + "uniform float iSampleRate;\n" + "uniform vec3 iChannelResolution[4];\n"; // not to be used by the hosted shader, but by our code in the middle on the gpu. // gpu code injection. first take. //"uniform float fZoom;\n"; headerlength += 7; for (var i = 0; i < mInputs.Length; i++) { var inp = mInputs[i]; // X:\jsc.svn\examples\javascript\chrome\apps\WebGL\ChromeShaderToyVRCardboardGrid\ChromeShaderToyVRCardboardGrid\Application.cs //if (inp != null && inp.mInfo.mType == "cubemap") if (inp is samplerCube) { new IHTMLPre { "add MakeHeader_Image samplerCube" }.AttachToDocument(); header += "uniform samplerCube iChannel" + i + ";\n"; } else { //new IHTMLPre { "add MakeHeader_Image sampler2D" }.AttachToDocument(); header += "uniform sampler2D iChannel" + i + ";\n"; } headerlength++; } // rror CreateShader {{ infoLog = ERROR: 0:250: 'assign' : l-value required "gl_FragCoord" (can't modify gl_FragCoord) // ERROR: 0:251: 'assign' : l - value required "gl_FragCoord"(can't modify gl_FragCoord) //}} // error CreateShader {{ infoLog = ERROR: 0:253: '=' : cannot convert from 'FragCoord mediump 4-component vector of float' to 'highp 2-component vector of float' var mImagePassFooter = @" void main( void ) { vec4 color = gl_FragColor; color.a = 1.0; mainImage( color, gl_FragCoord.xy ); gl_FragColor = color; } "; #endregion this.NewShader_Image = (fs) => { #region NewShader_Image //new IHTMLPre { "enter NewShader_Image" }.AttachToDocument(); var shaderCode = fs.ToString(); // is that it? var vsSource = "attribute vec2 pos; void main() { gl_Position = vec4(pos.xy,0.0,1.0); }"; var fsSource = header + shaderCode + mImagePassFooter; this.xCreateShader = CreateShader(gl, vsSource, fsSource, false); #endregion var vbo = new WebGLBuffer(gl); #region calledby //EffectPass.Paint_Image(effect.js:724) //EffectPass.Paint(effect.js:1038) //Effect.Paint(effect.js:1247) //renderLoop2(pgWatch.js:404) //ShaderToy.startRendering(pgWatch.js:420) //watchInit(pgWatch.js:1386) //onload(Xls3WS: 78) #endregion this.Paint_Image = (time, mouseOriX, mouseOriY, mousePosX, mousePosY, zoom) => { var mProgram = xCreateShader.mProgram; var xres = gl.canvas.width * zoom; var yres = gl.canvas.height * zoom; #region Paint_Image //new IHTMLPre { "enter Paint_Image" }.AttachToDocument(); // this is enough to do pip to bottom left, no need to adjust vertex positions even? gl.viewport(0, 0, (int)xres, (int)yres); // useProgram: program not valid gl.useProgram(mProgram); if (this.ProgramSelected != null) this.ProgramSelected(mProgram); // uniform4fv var uniform4fv_mouse = new[] { mousePosX, mousePosY, mouseOriX, mouseOriY }; // X:\jsc.svn\examples\glsl\future\GLSLShaderToyPip\GLSLShaderToyPip\Application.cs //gl.getUniformLocation(mProgram, "fZoom").With(fZoom => gl.uniform1f(fZoom, zoom)); var l2 = gl.getUniformLocation(mProgram, "iGlobalTime"); if (l2 != null) gl.uniform1f(l2, time); var l3 = gl.getUniformLocation(mProgram, "iResolution"); if (l3 != null) gl.uniform3f(l3, xres, yres, 1.0f); var l4 = gl.getUniformLocation(mProgram, "iMouse"); if (l4 != null) gl.uniform4fv(l4, uniform4fv_mouse); // X:\jsc.svn\examples\javascript\chrome\apps\WebGL\synergy\SimpleDigitalClock\SimpleDigitalClock\Application.cs // uniform vec4 iDate; // (year, month, day, time in seconds) // http://bytes.com/topic/c-sharp/answers/258829-time-elapsed-since-midnight-c var now = DateTime.Now; //var sinceMidnight = now - DateTime.Today; var sinceMidnight = now - now.Date; var uniform4fv_dates = new float[] { now.Year, now.Month, now.Day, (float)sinceMidnight.TotalSeconds }; var l7 = gl.getUniformLocation(mProgram, "iDate"); if (l7 != null) gl.uniform4fv(l7, uniform4fv_dates); //var l9 = gl.getUniformLocation(this.mProgram, "iSampleRate"); if (l9 != null) gl.uniform1f(l9, this.mSampleRate); var ich0 = gl.getUniformLocation(mProgram, "iChannel0"); if (ich0 != null) gl.uniform1i(ich0, 0); var ich1 = gl.getUniformLocation(mProgram, "iChannel1"); if (ich1 != null) gl.uniform1i(ich1, 1); var ich2 = gl.getUniformLocation(mProgram, "iChannel2"); if (ich2 != null) gl.uniform1i(ich2, 2); var ich3 = gl.getUniformLocation(mProgram, "iChannel3"); if (ich3 != null) gl.uniform1i(ich3, 3); // what if there are other textures too? // X:\jsc.svn\examples\javascript\chrome\apps\WebGL\ChromeWebGLFrameBuffer\ChromeWebGLFrameBuffer\Application.cs //for (var i = 0; i < mInputs.Length; i++) //{ // var inp = mInputs[i]; // gl.activeTexture((uint)(gl.TEXTURE0 + i)); // if (inp == null) // { // gl.bindTexture(gl.TEXTURE_2D, null); // } //} var times = new[] { 0.0f, 0.0f, 0.0f, 0.0f }; var l5 = gl.getUniformLocation(mProgram, "iChannelTime"); if (l5 != null) gl.uniform1fv(l5, times); var resos = new float[12] { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; var l8 = gl.getUniformLocation(mProgram, "iChannelResolution"); if (l8 != null) gl.uniform3fv(l8, resos); // using ? var vec2pos = (uint)gl.getAttribLocation(mProgram, "pos"); //gl.bindBuffer(gl.ARRAY_BUFFER, quadVBO); gl.bindBuffer(gl.ARRAY_BUFFER, vbo); #region vertices float left = -1.0f; // y reversed? float bottom = -1.0f; float right = 1.0f; float top = 1.0f; var fvertices = new float[] { // left top left, bottom, // right top //right, -1.0f, right, bottom, // left bottom left, top, // right top //right, -1.0f, right, bottom, // right bottom //right, 1.0f, right, top, // left bottom left,top }; //var vertices = new Float32Array(fvertices); #endregion //gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); gl.bufferData(gl.ARRAY_BUFFER, fvertices, gl.STATIC_DRAW); gl.vertexAttribPointer(vec2pos, 2, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(vec2pos); // GL ERROR :GL_INVALID_OPERATION : glDrawArrays: attempt to render with no buffer attached to enabled attribute 1 gl.drawArrays(gl.TRIANGLES, 0, 6); // first frame is now visible gl.disableVertexAttribArray(vec2pos); gl.bindBuffer(gl.ARRAY_BUFFER, null); #endregion mFrame++; }; }; }; }
// X:\jsc.svn\examples\glsl\future\GLSLShaderToyPip\GLSLShaderToyPip\Application.cs public EffectPass( AudioContext wa = null, gl gl = null, string precission = null, bool supportDerivatives = false, RefreshTexturThumbailDelegate callback = null, object obj = null, bool forceMuted = false, bool forcePaused = false, // createQuadVBO // ARRAY_BUFFER WebGLBuffer quadVBO = null, GainNode outputGainNode = null ) { //new IHTMLPre { "enter EffectPass" }.AttachToDocument(); // used by? var mFrame = 0; // http://math.hws.edu/eck/cs424/notes2013/19_GLSL.html // http://stackoverflow.com/questions/10079368/how-would-i-do-environment-reflection-in-webgl-without-using-a-library-like-thre this.MakeHeader_Image = delegate { #region MakeHeader_Image //new IHTMLPre { "enter MakeHeader_Image" }.AttachToDocument(); var header = precission; var headerlength = 3; if (supportDerivatives) { header += "#extension GL_OES_standard_derivatives : enable\n"; headerlength++; } header += "uniform vec3 iResolution;\n" + "uniform float iGlobalTime;\n" + "uniform float iChannelTime[4];\n" + "uniform vec4 iMouse;\n" + "uniform vec4 iDate;\n" + "uniform float iSampleRate;\n" + "uniform vec3 iChannelResolution[4];\n"; // not to be used by the hosted shader, but by our code in the middle on the gpu. // gpu code injection. first take. //"uniform float fZoom;\n"; headerlength += 7; for (var i = 0; i < mInputs.Length; i++) { var inp = mInputs[i]; // X:\jsc.svn\examples\javascript\chrome\apps\WebGL\ChromeShaderToyVRCardboardGrid\ChromeShaderToyVRCardboardGrid\Application.cs //if (inp != null && inp.mInfo.mType == "cubemap") if (inp is samplerCube) { //new IHTMLPre { "add MakeHeader_Image samplerCube" }.AttachToDocument(); this.tex = new WebGLTexture(gl); // http://stackoverflow.com/questions/10079368/how-would-i-do-environment-reflection-in-webgl-without-using-a-library-like-thre // view-source:https://www.shadertoy.com/js/effect.js // um can there be only one samplerCube? gl.activeTexture(gl.TEXTURE0); //gl.enable(gl.TEXTURE_CUBE_MAP); gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex); //gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, (int)gl.CLAMP_TO_EDGE); //gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, (int)gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, (int)gl.LINEAR); gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, (int)gl.LINEAR); //var cube0 = new IHTMLImage[] { // new HTML.Images.FromAssets.cube02_0(), // new HTML.Images.FromAssets.cube02_1(), // new HTML.Images.FromAssets.cube02_2(), // new HTML.Images.FromAssets.cube02_3(), // new HTML.Images.FromAssets.cube02_4(), // new HTML.Images.FromAssets.cube02_5() //}; //public const uint TEXTURE_CUBE_MAP_POSITIVE_X = 34069; //public const uint TEXTURE_CUBE_MAP_NEGATIVE_X = 34070; //public const uint TEXTURE_CUBE_MAP_POSITIVE_Y = 34071; //public const uint TEXTURE_CUBE_MAP_NEGATIVE_Y = 34072; //public const uint TEXTURE_CUBE_MAP_POSITIVE_Z = 34073; //public const uint TEXTURE_CUBE_MAP_NEGATIVE_Z = 34074; //var cube0 = new IHTMLImage[] { // new CSS3DPanoramaByHumus.HTML.Images.FromAssets.humus_px(), // new CSS3DPanoramaByHumus.HTML.Images.FromAssets.humus_nx(), // new CSS3DPanoramaByHumus.HTML.Images.FromAssets.humus_py(), // new CSS3DPanoramaByHumus.HTML.Images.FromAssets.humus_ny(), // new CSS3DPanoramaByHumus.HTML.Images.FromAssets.humus_pz(), // new CSS3DPanoramaByHumus.HTML.Images.FromAssets.humus_nz() //}; //cube0.WithEachIndex( // (pendingimg, index) => // { // pendingimg.InvokeOnComplete( // img => // { // gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex); // //gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); // gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 0); // gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + (uint)index, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img); // new IHTMLPre { "add MakeHeader_Image samplerCube TEXTURE_CUBE_MAP_POSITIVE_X + " + new { index } }.AttachToDocument(); // if (index == 5) // { // new IHTMLPre { "add MakeHeader_Image samplerCube activeTexture " }.AttachToDocument(); // // samplerCube iChannel0; = 0 = TEXTURE0 // } // // https://code.google.com/p/opengles-book-samples/source/browse/trunk/WebGL/Chapter_9/Simple_TextureCubemap/Simple_TextureCubemap.html?r=5 // // http://stackoverflow.com/questions/31665132/gl-invalid-operation-caused-by-samplercube // // http://forum.processing.org/two/discussion/7039/samplercube-and-ambient-reflection // } // ); // } //); header += "uniform samplerCube iChannel" + i + ";\n"; } else { //new IHTMLPre { "add MakeHeader_Image sampler2D" }.AttachToDocument(); header += "uniform sampler2D iChannel" + i + ";\n"; } // dont need it? headerlength++; } // rror CreateShader {{ infoLog = ERROR: 0:250: 'assign' : l-value required "gl_FragCoord" (can't modify gl_FragCoord) // ERROR: 0:251: 'assign' : l - value required "gl_FragCoord"(can't modify gl_FragCoord) //}} // error CreateShader {{ infoLog = ERROR: 0:253: '=' : cannot convert from 'FragCoord mediump 4-component vector of float' to 'highp 2-component vector of float' var mImagePassFooter = @" void main( void ) { vec4 color = gl_FragColor; color.a = 1.0; mainImage( color, gl_FragCoord.xy ); gl_FragColor = color; } "; #endregion this.NewShader_Image = (fs) => { #region NewShader_Image //new IHTMLPre { "enter NewShader_Image" }.AttachToDocument(); var shaderCode = fs.ToString(); // is that it? var vsSource = "attribute vec2 pos; void main() { gl_Position = vec4(pos.xy,0.0,1.0); }"; var fsSource = header + shaderCode + mImagePassFooter; this.xCreateShader = CreateShader(gl, vsSource, fsSource, false); #endregion var vbo = new WebGLBuffer(gl); #region calledby //EffectPass.Paint_Image(effect.js:724) //EffectPass.Paint(effect.js:1038) //Effect.Paint(effect.js:1247) //renderLoop2(pgWatch.js:404) //ShaderToy.startRendering(pgWatch.js:420) //watchInit(pgWatch.js:1386) //onload(Xls3WS: 78) #endregion this.Paint_Image = (time, mouseOriX, mouseOriY, mousePosX, mousePosY, zoom) => { var mProgram = xCreateShader.mProgram; var xres = gl.canvas.width * zoom; var yres = gl.canvas.height * zoom; #region Paint_Image //new IHTMLPre { "enter Paint_Image" }.AttachToDocument(); // this is enough to do pip to bottom left, no need to adjust vertex positions even? gl.viewport(0, 0, (int)xres, (int)yres); // useProgram: program not valid gl.useProgram(mProgram); // uniform4fv var uniform4fv_mouse = new[] { mousePosX, mousePosY, mouseOriX, mouseOriY }; // X:\jsc.svn\examples\glsl\future\GLSLShaderToyPip\GLSLShaderToyPip\Application.cs //gl.getUniformLocation(mProgram, "fZoom").With(fZoom => gl.uniform1f(fZoom, zoom)); var l2 = gl.getUniformLocation(mProgram, "iGlobalTime"); if (l2 != null) gl.uniform1f(l2, time); var l3 = gl.getUniformLocation(mProgram, "iResolution"); if (l3 != null) gl.uniform3f(l3, xres, yres, 1.0f); var l4 = gl.getUniformLocation(mProgram, "iMouse"); if (l4 != null) gl.uniform4fv(l4, uniform4fv_mouse); // X:\jsc.svn\examples\javascript\chrome\apps\WebGL\synergy\SimpleDigitalClock\SimpleDigitalClock\Application.cs // uniform vec4 iDate; // (year, month, day, time in seconds) // http://bytes.com/topic/c-sharp/answers/258829-time-elapsed-since-midnight-c var now = DateTime.Now; //var sinceMidnight = now - DateTime.Today; var sinceMidnight = now - now.Date; var uniform4fv_dates = new float[] { now.Year, now.Month, now.Day, (float)sinceMidnight.TotalSeconds }; var l7 = gl.getUniformLocation(mProgram, "iDate"); if (l7 != null) gl.uniform4fv(l7, uniform4fv_dates); //var l9 = gl.getUniformLocation(this.mProgram, "iSampleRate"); if (l9 != null) gl.uniform1f(l9, this.mSampleRate); //var ich0 = gl.getUniformLocation(mProgram, "iChannel0"); if (ich0 != null) gl.uniform1i(ich0, 0); //var ich1 = gl.getUniformLocation(mProgram, "iChannel1"); if (ich1 != null) gl.uniform1i(ich1, 1); //var ich2 = gl.getUniformLocation(mProgram, "iChannel2"); if (ich2 != null) gl.uniform1i(ich2, 2); //var ich3 = gl.getUniformLocation(mProgram, "iChannel3"); if (ich3 != null) gl.uniform1i(ich3, 3); // what if there are other textures too? // X:\jsc.svn\examples\javascript\chrome\apps\WebGL\ChromeWebGLFrameBuffer\ChromeWebGLFrameBuffer\Application.cs //for (var i = 0; i < mInputs.Length; i++) //{ // var inp = mInputs[i]; // gl.activeTexture((uint)(gl.TEXTURE0 + i)); // if (inp == null) // { // gl.bindTexture(gl.TEXTURE_2D, null); // } //} var times = new[] { 0.0f, 0.0f, 0.0f, 0.0f }; var l5 = gl.getUniformLocation(mProgram, "iChannelTime"); if (l5 != null) gl.uniform1fv(l5, times); var resos = new float[12] { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; var l8 = gl.getUniformLocation(mProgram, "iChannelResolution"); if (l8 != null) gl.uniform3fv(l8, resos); // using ? var vec2pos = (uint)gl.getAttribLocation(mProgram, "pos"); //gl.bindBuffer(gl.ARRAY_BUFFER, quadVBO); gl.bindBuffer(gl.ARRAY_BUFFER, vbo); #region vertices float left = -1.0f; // y reversed? float bottom = -1.0f; float right = 1.0f; float top = 1.0f; var fvertices = new float[] { // left top left, bottom, // right top //right, -1.0f, right, bottom, // left bottom left, top, // right top //right, -1.0f, right, bottom, // right bottom //right, 1.0f, right, top, // left bottom left,top }; #endregion gl.bufferData(gl.ARRAY_BUFFER, fvertices, gl.STATIC_DRAW); gl.vertexAttribPointer(vec2pos, 2, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(vec2pos); //var iChannel0 = gl.getUniformLocation(mProgram, "iChannel0"); // GL ERROR :GL_INVALID_OPERATION : glDrawArrays: attempt to render with no buffer attached to enabled attribute 1 gl.drawArrays(gl.TRIANGLES, 0, 6); // first frame is now visible gl.disableVertexAttribArray(vec2pos); gl.bindBuffer(gl.ARRAY_BUFFER, null); #endregion mFrame++; }; }; }; }
// https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150719/chromeudpwindwheel /// <summary> /// This is a javascript application. /// </summary> /// <param name="page">HTML document rendered by the web server which can now be enhanced.</param> public Application(IApp page) { #region += Launched chrome.app.window dynamic self = Native.self; dynamic self_chrome = self.chrome; object self_chrome_socket = self_chrome.socket; if (self_chrome_socket != null) { if (!(Native.window.opener == null && Native.window.parent == Native.window.self)) { Console.WriteLine("chrome.app.window.create, is that you?"); // pass thru } else { // should jsc send a copresence udp message? chrome.runtime.UpdateAvailable += delegate { new chrome.Notification(title: "UpdateAvailable"); }; chrome.app.runtime.Launched += async delegate { // 0:12094ms chrome.app.window.create {{ href = chrome-extension://aemlnmcokphbneegoefdckonejmknohh/_generated_background_page.html }} Console.WriteLine("chrome.app.window.create " + new { Native.document.location.href }); new chrome.Notification(title: "ChromeUDPSendAsync"); // https://developer.chrome.com/apps/app_window#type-CreateWindowOptions var xappwindow = await chrome.app.window.create( Native.document.location.pathname, options: new { alwaysOnTop = true, visibleOnAllWorkspaces = true } ); //xappwindow.setAlwaysOnTop xappwindow.show(); await xappwindow.contentWindow.async.onload; Console.WriteLine("chrome.app.window loaded!"); }; return; } } #endregion // X:\jsc.svn\examples\javascript\WorkerMD5Experiment\WorkerMD5Experiment\Application.cs // "C:\Users\Arvo\AppData\Local\Google\Chrome SxS\Application\chrome.exe - es3.lnk" var size = 600; var gl = new WebGLRenderingContext(); var canvas = gl.canvas.AttachToDocument(); Native.document.body.style.overflow = IStyle.OverflowEnum.hidden; canvas.style.SetLocation(0, 0, size, size); canvas.width = size; canvas.height = size; var gl_viewportWidth = size; var gl_viewportHeight = size; // can AssetLibrary create a special type // and define the variables // for it we need to parse glsl? // if we dont parse the code yet, // do we parse the macros and fields neogh already to do that? // Geometry var shaderProgram = gl.createProgram( new WebGLWindWheel.Shaders.GeometryVertexShader(), new WebGLWindWheel.Shaders.GeometryFragmentShader() ); gl.linkProgram(shaderProgram); gl.useProgram(shaderProgram); var shaderProgram_vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); gl.enableVertexAttribArray((uint)shaderProgram_vertexPositionAttribute); // new in lesson 02 var shaderProgram_vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor"); gl.enableVertexAttribArray((uint)shaderProgram_vertexColorAttribute); var shaderProgram_pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); var shaderProgram_mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); // https://hacks.mozilla.org/2014/10/introducing-simd-js/ // https://github.com/toji/gl-matrix/blob/master/src/gl-matrix/mat4.js // http://www.i-programmer.info/news/167-javascript/8578-chrome-to-support-simdjs.html // https://code.google.com/p/v8/issues/detail?id=2228 //var SIMD_mat4 = new System.Numerics.Matrix4x4(); //var SIMD_mat4s = new Stack<System.Numerics.Matrix4x4>(); // can we convert this code to NDK friendly non GC library? // for gearVR 90FOV and cardboard wearality 150FOV #region __mat4 var __mat4 = new { // X:\jsc.svn\examples\javascript\Test\TestFloatArray\TestFloatArray\Application.cs // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2015/20150706/20150708 // generic in the sens of caller choosing is the return type a new struct or out ref? perspective = new Func<float[], float, float, float, float, float[]>( (that, fovy, aspect, near, far) => { var f = 1.0f / (float)Math.Tan(fovy / 2f); var nf = 1f / (near - far); that[0] = f / aspect; that[1] = 0; that[2] = 0; that[3] = 0; that[4] = 0; that[5] = f; that[6] = 0; that[7] = 0; that[8] = 0; that[9] = 0; that[10] = (far + near) * nf; that[11] = -1; that[12] = 0; that[13] = 0; that[14] = (2 * far * near) * nf; that[15] = 0; return that; }), // reset content of mat4 identity = new Func<float[], float[]>( that => { //Array.Copy() //var xx =&that; var xx = new float[] { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, }; //is this the best way to update array contents? xx.CopyTo(that, 0); return xx; } ), create = new Func<float[]>( () => //new mat4() new float[] { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, } ), #region not used? clone = new Func<float[], float[]>( smat4 => //new mat4() new float[] { smat4[0], smat4[1], smat4[2], smat4[3], smat4[4], smat4[5], smat4[6], smat4[7], smat4[8], smat4[9], smat4[10], smat4[11], smat4[12], smat4[13], smat4[14], smat4[15], } ) #endregion , // X:\jsc.svn\examples\java\android\vr\OVRWindWheelNDK\OVRWindWheelNDK\References\VrApi.ovrMatrix4f.cs translate = new Func<float[], float[], float[], float[]>( (float[] that, float[] output, float[] xyz) => { float xx = xyz[0], y = xyz[1], z = xyz[2]; if (output == that) { that[12] = output[0] * xx + output[4] * y + output[8] * z + output[12]; that[13] = output[1] * xx + output[5] * y + output[9] * z + output[13]; that[14] = output[2] * xx + output[6] * y + output[10] * z + output[14]; that[15] = output[3] * xx + output[7] * y + output[11] * z + output[15]; return that; } float a00, a01, a02, a03, a10, a11, a12, a13, a20, a21, a22, a23; a00 = output[0]; a01 = output[1]; a02 = output[2]; a03 = output[3]; a10 = output[4]; a11 = output[5]; a12 = output[6]; a13 = output[7]; a20 = output[8]; a21 = output[9]; a22 = output[10]; a23 = output[11]; that[0] = a00; that[1] = a01; that[2] = a02; that[3] = a03; that[4] = a10; that[5] = a11; that[6] = a12; that[7] = a13; that[8] = a20; that[9] = a21; that[10] = a22; that[11] = a23; that[12] = a00 * xx + a10 * y + a20 * z + output[12]; that[13] = a01 * xx + a11 * y + a21 * z + output[13]; that[14] = a02 * xx + a12 * y + a22 * z + output[14]; that[15] = a03 * xx + a13 * y + a23 * z + output[15]; return that; } ), rotate = new Func<float[], float[], float, float[], float[]>( (that, a, rad, axis) => { float x = axis[0], y = axis[1], z = axis[2]; float len = (float)Math.Sqrt(x * x + y * y + z * z), s, c, t, a00, a01, a02, a03, a10, a11, a12, a13, a20, a21, a22, a23, b00, b01, b02, b10, b11, b12, b20, b21, b22; if (Math.Abs(len) < float.Epsilon) return that; len = 1f / len; x *= len; y *= len; z *= len; s = (float)Math.Sin(rad); c = (float)Math.Cos(rad); t = 1 - c; a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3]; a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7]; a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11]; // Construct the elements of the rotation matrix b00 = x * x * t + c; b01 = y * x * t + z * s; b02 = z * x * t - y * s; b10 = x * y * t - z * s; b11 = y * y * t + c; b12 = z * y * t + x * s; b20 = x * z * t + y * s; b21 = y * z * t - x * s; b22 = z * z * t + c; // Perform rotation-specific matrix multiplication that[0] = a00 * b00 + a10 * b01 + a20 * b02; that[1] = a01 * b00 + a11 * b01 + a21 * b02; that[2] = a02 * b00 + a12 * b01 + a22 * b02; that[3] = a03 * b00 + a13 * b01 + a23 * b02; that[4] = a00 * b10 + a10 * b11 + a20 * b12; that[5] = a01 * b10 + a11 * b11 + a21 * b12; that[6] = a02 * b10 + a12 * b11 + a22 * b12; that[7] = a03 * b10 + a13 * b11 + a23 * b12; that[8] = a00 * b20 + a10 * b21 + a20 * b22; that[9] = a01 * b20 + a11 * b21 + a21 * b22; that[10] = a02 * b20 + a12 * b21 + a22 * b22; that[11] = a03 * b20 + a13 * b21 + a23 * b22; if (a != that) { // If the source and destination differ, copy the unchanged last row that[12] = a[12]; that[13] = a[13]; that[14] = a[14]; that[15] = a[15]; } return that; } ) }; #endregion // set to identity var mvMatrix = __mat4.create(); var mvMatrixStack = new Stack<float[]>(); // set to perspective var pMatrix = __mat4.create(); #region new in lesson 03 // how would this translate to non GC, NDK? Action mvPushMatrix = delegate { var copy = __mat4.create(); mvMatrix.CopyTo(copy, 0); //glMatrix.mat4.set(mvMatrix, copy); mvMatrixStack.Push(copy); }; Action mvPopMatrix = delegate { mvMatrix = mvMatrixStack.Pop(); }; #endregion #region setMatrixUniforms Action setMatrixUniforms = delegate { gl.uniformMatrix4fv(shaderProgram_pMatrixUniform, false, pMatrix); gl.uniformMatrix4fv(shaderProgram_mvMatrixUniform, false, mvMatrix); }; #endregion #region init buffers #region cube var cubeVertexPositionBuffer = new WebGLBuffer(gl); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); //var cubesize = 1.0f * 0.05f; //var cubesize = 1.0f * 0.1f; var cubesize = 16 / 128f; //var cubesize = 1.0f; var vertices = new[]{ // Front face -cubesize, -cubesize, cubesize, cubesize, -cubesize, cubesize, cubesize, cubesize, cubesize, -cubesize, cubesize, cubesize, // Back face -cubesize, -cubesize, -cubesize, -cubesize, cubesize, -cubesize, cubesize, cubesize, -cubesize, cubesize, -cubesize, -cubesize, // Top face -cubesize, cubesize, -cubesize, -cubesize, cubesize, cubesize, cubesize, cubesize, cubesize, cubesize, cubesize, -cubesize, // Bottom face -cubesize, -cubesize, -cubesize, cubesize, -cubesize, -cubesize, cubesize, -cubesize, cubesize, -cubesize, -cubesize, cubesize, // Right face cubesize, -cubesize, -cubesize, cubesize, cubesize, -cubesize, cubesize, cubesize, cubesize, cubesize, -cubesize, cubesize, // Left face -cubesize, -cubesize, -cubesize, -cubesize, -cubesize, cubesize, -cubesize, cubesize, cubesize, -cubesize, cubesize, -cubesize }; gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); var cubeVertexPositionBuffer_itemSize = 3; var cubeVertexPositionBuffer_numItems = 6 * 6; var squareVertexColorBuffer = new WebGLBuffer(gl); gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexColorBuffer); // 216, 191, 18 var colors = new[]{ 1.0f, 0.6f, 0.0f, 1.0f, // Front face 1.0f, 0.6f, 0.0f, 1.0f, // Front face 1.0f, 0.6f, 0.0f, 1.0f, // Front face 1.0f, 0.6f, 0.0f, 1.0f, // Front face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Left face 1.0f, 0.8f, 0.0f, 1.0f, // Left face 1.0f, 0.8f, 0.0f, 1.0f, // Left face 1.0f, 0.8f, 0.0f, 1.0f // Left face }; gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW); var cubeVertexColorBuffer_itemSize = 4; var cubeVertexColorBuffer_numItems = 24; // ELEMENT_ARRAY_BUFFER : WebGLBuffer? // drawElements var cubeVertexIndexBuffer = new WebGLBuffer(gl); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); //var cubeVertexIndices = new UInt16[]{ var cubeVertexIndices = new byte[]{ 0, 1, 2, 0, 2, 3, // Front face 4, 5, 6, 4, 6, 7, // Back face 8, 9, 10, 8, 10, 11, // Top face 12, 13, 14, 12, 14, 15, // Bottom face 16, 17, 18, 16, 18, 19, // Right face 20, 21, 22, 20, 22, 23 // Left face }; // ushort[]? //gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndices, gl.STATIC_DRAW); var cubeVertexIndexBuffer_itemSize = 1; var cubeVertexIndexBuffer_numItems = 36; #endregion #endregion gl.clearColor(0.0f, 0.0f, 0.0f, alpha: 1.0f); gl.enable(gl.DEPTH_TEST); var rWindDelta = 0.1f; var rCubeDelta = 1.0f; var rCube = 0f; var rWind = 0f; var lastTime = 0L; Action animate = delegate { var timeNow = new IDate().getTime(); if (lastTime != 0) { var elapsed = timeNow - lastTime; rCube -= ((75 * elapsed) / 1000.0f) * rCubeDelta; rWind -= ((75 * elapsed) / 1000.0f) * rWindDelta; } lastTime = timeNow; }; #region degToRad Func<float, float> degToRad = (degrees) => { return degrees * (float)Math.PI / 180f; }; #endregion #region AtResize Action AtResize = delegate { gl_viewportWidth = Native.window.Width; gl_viewportHeight = Native.window.Height; canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportHeight); canvas.width = gl_viewportWidth; canvas.height = gl_viewportHeight; }; Native.window.onresize += e => { AtResize(); }; AtResize(); #endregion #region ui to vr var keys_ad = 0; var keys_ws = 0; var keys_c = 0; var mousebutton = 0; var mousewheel = 0; var mx = 0; var my = 0; #endregion canvas.tabIndex = 1; #region onkeydown canvas.onkeydown += async e => { var A = e.KeyCode == 65; var D = e.KeyCode == 68; if (A || D) { keys_ad = e.KeyCode; //Native.document.title = new { e.CursorX, e.CursorY }.ToString(); //wasd.innerText = new { e.KeyCode, ad = keys_ad, ws = keys_ws }.ToString(); while ((await canvas.async.onkeyup).KeyCode != e.KeyCode) ; //var ee = await div.async.onkeyup; keys_ad = 0; //wasd.innerText = new { e.KeyCode, ad = keys_ad, ws = keys_ws }.ToString(); return; } // CS // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150704 if (e.KeyCode == 67) { keys_c = e.KeyCode; //Native.document.title = new { e.CursorX, e.CursorY }.ToString(); //wasd.innerText = new { e.KeyCode, keys_ad, keys_ws, keys_c }.ToString(); while ((await canvas.async.onkeyup).KeyCode != e.KeyCode) ; //var ee = await div.async.onkeyup; keys_c = 0; //wasd.innerText = new { e.KeyCode, keys_ad, keys_ws, keys_c }.ToString(); return; } { keys_ws = e.KeyCode; //Native.document.title = new { e.CursorX, e.CursorY }.ToString(); //wasd.innerText = new { e.KeyCode, ad = keys_ad, ws = keys_ws }.ToString(); while ((await canvas.async.onkeyup).KeyCode != e.KeyCode) ; //var ee = await div.async.onkeyup; keys_ws = 0; //wasd.innerText = new { e.KeyCode, ad = keys_ad, ws = keys_ws }.ToString(); } }; #endregion #region onmousemove canvas.onmousewheel += e => { // since we are a chrome app. is chrome sending us wheel delta too? mousewheel += e.WheelDirection; }; canvas.onmousemove += e => { // we could tilt the svg cursor // like we do on heat zeeker:D mx += e.movementX; my += e.movementY; //Native.document.title = new { e.CursorX, e.CursorY }.ToString(); //xy.innerText = new { x, y }.ToString(); }; canvas.onmousedown += async e => { // wont work for RemoteApp users tho mousebutton = (int)e.MouseButton; // await ? canvas.requestPointerLock(); //e.CaptureMouse(); var ee = await canvas.async.onmouseup; //var ee = await div.async.ondblclick; if (ee.MouseButton == IEvent.MouseButtonEnum.Right) Native.document.exitPointerLock(); mousebutton = 0; }; #endregion var vertexTransform = new float[0]; new { }.With( async delegate { var n = await chrome.socket.getNetworkList(); var n24 = n.Where(nn => nn.prefixLength == 24).ToArray(); n24.WithEach( async nic => { var port = new Random().Next(16000, 40000); var socket = new UdpClient(); socket.Client.Bind( //new IPEndPoint(IPAddress.Any, port: 40000) new IPEndPoint(IPAddress.Parse(nic.address), port) ); // this will eat too much memory? //div.ownerDocument.defaultView.onframe += canvas.onframe += delegate { // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150704 var nmessage = mx + ":" + my + ":" + keys_ad + ":" + keys_ws + ":" + keys_c + ":" + mousebutton + ":" + mousewheel; var data = Encoding.UTF8.GetBytes(nmessage); //creates a variable b of type byte //new IHTMLPre { "about to send... " + new { data.Length } }.AttachToDocument(); // X:\jsc.svn\examples\javascript\chrome\apps\ChromeUDPNotification\ChromeUDPNotification\Application.cs socket.Send( data, data.Length, hostname: "239.1.2.3", port: 41814 ); }; var uu = new UdpClient(40014); uu.JoinMulticastGroup(IPAddress.Parse("239.1.2.3")); while (true) { var xx = await uu.ReceiveAsync(); // did we jump to ui thread? // https://www.khronos.org/registry/typedarray/specs/latest/ vertexTransform = new Float32Array(new Uint8ClampedArray(xx.Buffer).buffer); } } ); } ); var sw = Stopwatch.StartNew(); Native.window.onframe += e => { gl.viewport(0, 0, gl_viewportWidth, gl_viewportHeight); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); #region pMatrix __mat4.perspective( pMatrix, 90f, (float)gl_viewportWidth / (float)gl_viewportHeight, 0.1f, 100.0f ); //__mat4.rotate(pMatrix, pMatrix, (float)Math.PI + mx * 0.005f, new float[] { 0, 1f, 0f }); __mat4.rotate(pMatrix, pMatrix, mx * 0.005f, new float[] { 0, 1f, 0f }); #endregion //var cubesize = 1.0f * 0.05f; if (vertexTransform.Length == 0) { __mat4.identity(mvMatrix); __mat4.translate(mvMatrix, mvMatrix, new float[] { -1.5f, 0.0f, -3.0f }); #region windwheel mvPushMatrix(); __mat4.rotate(mvMatrix, mvMatrix, degToRad(rWind), new float[] { 0, 1f, 0f }); #region DrawFrameworkWingAtX Action<float, float> DrawFrameworkWingAtX = (WingX, WingY) => { mvPushMatrix(); __mat4.translate(mvMatrix, mvMatrix, new float[] { cubesize * WingX, cubesize * WingY, 0 }); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, cubeVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexColorBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); setMatrixUniforms(); gl.drawElements(gl.TRIANGLES, cubeVertexPositionBuffer_numItems, gl.UNSIGNED_BYTE, 0); mvPopMatrix(); }; #endregion #region DrawWingAtX Action<int, int, float, float> DrawWingAtX = (WingX, WingSize, WingRotationMultiplier, WingRotationOffset) => { mvPushMatrix(); __mat4.translate(mvMatrix, mvMatrix, new float[] { cubesize * WingX, 0, 0 }); if (WingRotationOffset == 0) { DrawFrameworkWingAtX(0, 0); } #region DrawWingPart Action<float> DrawWingPart = PartIndex => { mvPushMatrix(); __mat4.rotate(mvMatrix, mvMatrix, degToRad(WingRotationOffset + (rCube * WingRotationMultiplier)), new float[] { 1f, 0f, 0f }); __mat4.translate(mvMatrix, mvMatrix, new float[] { 0f, cubesize * PartIndex * 2, 0 }); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, cubeVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexColorBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); setMatrixUniforms(); gl.drawElements(gl.TRIANGLES, cubeVertexPositionBuffer_numItems, gl.UNSIGNED_BYTE, 0); mvPopMatrix(); }; #endregion #region DrawWingWithSize Action<int> DrawWingWithSize = length => { for (int i = 4; i < length; i++) { DrawWingPart(i * 1.0f); DrawWingPart(-i * 1.0f); } }; #endregion DrawWingWithSize(WingSize); mvPopMatrix(); }; #endregion var x = 8; DrawFrameworkWingAtX(x - 8, 0); for (int i = 0; i < 24; i++) { DrawFrameworkWingAtX(x - 8, -2.0f * i); } DrawWingAtX(x - 6, 0, 1f, 0); DrawWingAtX(x - 4, 0, 1f, 0); DrawWingAtX(x - 2, 0, 1f, 0); DrawWingAtX(x + 0, 16, 1f, 0); DrawWingAtX(x + 0, 16, 1f, 30); DrawWingAtX(x + 0, 16, 1f, 60); DrawWingAtX(x + 0, 16, 1f, 90); DrawWingAtX(x + 0, 16, 1f, 120); DrawWingAtX(x + 0, 16, 1f, 150); DrawWingAtX(x + 2, 0, 1f, 0); DrawWingAtX(x + 4, 0, 1f, 0); DrawWingAtX(x + 6, 0, 1f, 0); DrawWingAtX(x + 8, 12, 0.4f, 0); DrawWingAtX(x + 8, 12, 0.4f, 60); DrawWingAtX(x + 8, 12, 0.4f, 120); DrawWingAtX(x + 8 + 2, 0, 1f, 0); DrawWingAtX(x + 8 + 4, 0, 1f, 0); DrawWingAtX(x + 8 + 6, 0, 1f, 0); DrawWingAtX(x + 16, 8, 0.3f, 0); DrawWingAtX(x + 16, 8, 0.3f, 90); mvPopMatrix(); #endregion } #region draw cube on the right to remind where we started //glMatrix.mat4.translate(mvMatrix, new float[] { 3.0f, 2.0f, 0.0f }); // how do we scale it? //mvMatrix = __mat4.create(); //mvMatrix = new float[] //{ // 1, 0, 0, 0, // 0, 1, 0, 0, // 0, 0, 1, 0, // 0, 0, 0, 1, //}; //f = new Float32Array( [1, 0, 0, 1.5, 0, 1, 0, 2, 0, 0, 1, -3, 0, 0, 0, 1]); //a[0].__mat4.identity.WRMABg6gjTWKCO_aNXgMMAA(a[0].mvMatrix); //a[0].__mat4.translate.YRMABiCCKT_aaNWnR3f4qdg(a[0].mvMatrix, a[0].mvMatrix, new Float32Array( [1.5, 2, -3])); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, cubeVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexColorBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); gl.uniformMatrix4fv(shaderProgram_pMatrixUniform, false, pMatrix); // https://www.physicsforums.com/threads/what-is-the-purpose-of-the-transpose.261849/ var mvMatrix0transpose = new float[] { 9, 0, 0,0, 0, 4, 0, 0, 0, 0, 4, 0, 1.5f, 2.0f, -9.0f, 1, }; // X:\jsc.svn\examples\javascript\chrome\apps\ChromeUDPFloats\ChromeUDPFloats\Application.cs var ElementCount = vertexTransform.Length / (64 / 4); for (int ElementIndex = 0; ElementIndex < ElementCount; ElementIndex++) { var mvMatrix0 = new float[16]; for (int j = 0; j < 16; j++) { var ff = vertexTransform[j + ElementIndex * 64 / 4]; //Console.WriteLine(new { j, ff }); mvMatrix0[j] = ff; } mvMatrix0transpose = new[] { mvMatrix0[0], mvMatrix0[4], mvMatrix0[8],mvMatrix0[12], mvMatrix0[1],mvMatrix0[5],mvMatrix0[9],mvMatrix0[13], mvMatrix0[2],mvMatrix0[6],mvMatrix0[10],mvMatrix0[14], mvMatrix0[3],mvMatrix0[7],mvMatrix0[11],mvMatrix0[15] }; gl.uniformMatrix4fv(shaderProgram_mvMatrixUniform, false, mvMatrix0transpose); gl.drawElements(gl.TRIANGLES, cubeVertexPositionBuffer_numItems, gl.UNSIGNED_BYTE, 0); } #endregion animate(); }; }
/// <summary> /// This is a javascript application. /// </summary> /// <param name="page">HTML document rendered by the web server which can now be enhanced.</param> public Application(IDefault page = null) { var size = 600; var gl = new WebGLRenderingContext(); var canvas = gl.canvas.AttachToDocument(); Native.document.body.style.overflow = IStyle.OverflowEnum.hidden; canvas.style.SetLocation(0, 0, size, size); canvas.width = size; canvas.height = size; var gl_viewportWidth = size; var gl_viewportHeight = size; // can AssetLibrary create a special type // and define the variables // for it we need to parse glsl? // Geometry var shaderProgram = gl.createProgram( new GeometryVertexShader(), new GeometryFragmentShader() ); gl.linkProgram(shaderProgram); gl.useProgram(shaderProgram); var shaderProgram_vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); gl.enableVertexAttribArray((uint)shaderProgram_vertexPositionAttribute); // new in lesson 02 var shaderProgram_vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor"); gl.enableVertexAttribArray((uint)shaderProgram_vertexColorAttribute); var shaderProgram_pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); var shaderProgram_mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); // https://hacks.mozilla.org/2014/10/introducing-simd-js/ // https://github.com/toji/gl-matrix/blob/master/src/gl-matrix/mat4.js // http://www.i-programmer.info/news/167-javascript/8578-chrome-to-support-simdjs.html // https://code.google.com/p/v8/issues/detail?id=2228 var SIMD_mat4 = new System.Numerics.Matrix4x4(); var SIMD_mat4s = new Stack<System.Numerics.Matrix4x4>(); // can we convert this code to NDK friendly non GC library? // for gearVR 90FOV and cardboard wearality 150FOV #region __mat4 var __mat4 = new { // X:\jsc.svn\examples\javascript\Test\TestFloatArray\TestFloatArray\Application.cs // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2015/20150706/20150708 // generic in the sens of caller choosing is the return type a new struct or out ref? perspective = new Func<float[], float, float, float, float, float[]>( (that, fovy, aspect, near, far) => { var f = 1.0f / (float)Math.Tan(fovy / 2f); var nf = 1f / (near - far); that[0] = f / aspect; that[1] = 0; that[2] = 0; that[3] = 0; that[4] = 0; that[5] = f; that[6] = 0; that[7] = 0; that[8] = 0; that[9] = 0; that[10] = (far + near) * nf; that[11] = -1; that[12] = 0; that[13] = 0; that[14] = (2 * far * near) * nf; that[15] = 0; return that; }), // reset content of mat4 identity = new Func<float[], float[]>( that => { //Array.Copy() //var xx =&that; var x = new float[] { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, }; //is this the best way to update array contents? x.CopyTo(that, 0); return x; } ), create = new Func<float[]>( () => //new mat4() new float[] { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, } ), #region not used? clone = new Func<float[], float[]>( smat4 => //new mat4() new float[] { smat4[0], smat4[1], smat4[2], smat4[3], smat4[4], smat4[5], smat4[6], smat4[7], smat4[8], smat4[9], smat4[10], smat4[11], smat4[12], smat4[13], smat4[14], smat4[15], } ) #endregion , // X:\jsc.svn\examples\java\android\vr\OVRWindWheelNDK\OVRWindWheelNDK\References\VrApi.ovrMatrix4f.cs translate = new Func<float[], float[], float[], float[]>( (float[] that, float[] output, float[] xyz) => { float x = xyz[0], y = xyz[1], z = xyz[2]; if (output == that) { that[12] = output[0] * x + output[4] * y + output[8] * z + output[12]; that[13] = output[1] * x + output[5] * y + output[9] * z + output[13]; that[14] = output[2] * x + output[6] * y + output[10] * z + output[14]; that[15] = output[3] * x + output[7] * y + output[11] * z + output[15]; return that; } float a00, a01, a02, a03, a10, a11, a12, a13, a20, a21, a22, a23; a00 = output[0]; a01 = output[1]; a02 = output[2]; a03 = output[3]; a10 = output[4]; a11 = output[5]; a12 = output[6]; a13 = output[7]; a20 = output[8]; a21 = output[9]; a22 = output[10]; a23 = output[11]; that[0] = a00; that[1] = a01; that[2] = a02; that[3] = a03; that[4] = a10; that[5] = a11; that[6] = a12; that[7] = a13; that[8] = a20; that[9] = a21; that[10] = a22; that[11] = a23; that[12] = a00 * x + a10 * y + a20 * z + output[12]; that[13] = a01 * x + a11 * y + a21 * z + output[13]; that[14] = a02 * x + a12 * y + a22 * z + output[14]; that[15] = a03 * x + a13 * y + a23 * z + output[15]; return that; } ), rotate = new Func<float[], float[], float, float[], float[]>( (that, a, rad, axis) => { float x = axis[0], y = axis[1], z = axis[2]; float len = (float)Math.Sqrt(x * x + y * y + z * z), s, c, t, a00, a01, a02, a03, a10, a11, a12, a13, a20, a21, a22, a23, b00, b01, b02, b10, b11, b12, b20, b21, b22; if (Math.Abs(len) < float.Epsilon) return that; len = 1f / len; x *= len; y *= len; z *= len; s = (float)Math.Sin(rad); c = (float)Math.Cos(rad); t = 1 - c; a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3]; a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7]; a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11]; // Construct the elements of the rotation matrix b00 = x * x * t + c; b01 = y * x * t + z * s; b02 = z * x * t - y * s; b10 = x * y * t - z * s; b11 = y * y * t + c; b12 = z * y * t + x * s; b20 = x * z * t + y * s; b21 = y * z * t - x * s; b22 = z * z * t + c; // Perform rotation-specific matrix multiplication that[0] = a00 * b00 + a10 * b01 + a20 * b02; that[1] = a01 * b00 + a11 * b01 + a21 * b02; that[2] = a02 * b00 + a12 * b01 + a22 * b02; that[3] = a03 * b00 + a13 * b01 + a23 * b02; that[4] = a00 * b10 + a10 * b11 + a20 * b12; that[5] = a01 * b10 + a11 * b11 + a21 * b12; that[6] = a02 * b10 + a12 * b11 + a22 * b12; that[7] = a03 * b10 + a13 * b11 + a23 * b12; that[8] = a00 * b20 + a10 * b21 + a20 * b22; that[9] = a01 * b20 + a11 * b21 + a21 * b22; that[10] = a02 * b20 + a12 * b21 + a22 * b22; that[11] = a03 * b20 + a13 * b21 + a23 * b22; if (a != that) { // If the source and destination differ, copy the unchanged last row that[12] = a[12]; that[13] = a[13]; that[14] = a[14]; that[15] = a[15]; } return that; } ) }; #endregion // set to identity var mvMatrix = __mat4.create(); var mvMatrixStack = new Stack<float[]>(); // set to perspective var pMatrix = __mat4.create(); #region new in lesson 03 // how would this translate to non GC, NDK? Action mvPushMatrix = delegate { var copy = __mat4.create(); mvMatrix.CopyTo(copy, 0); //glMatrix.mat4.set(mvMatrix, copy); mvMatrixStack.Push(copy); }; Action mvPopMatrix = delegate { mvMatrix = mvMatrixStack.Pop(); }; #endregion #region setMatrixUniforms Action setMatrixUniforms = delegate { gl.uniformMatrix4fv(shaderProgram_pMatrixUniform, false, pMatrix); gl.uniformMatrix4fv(shaderProgram_mvMatrixUniform, false, mvMatrix); }; #endregion #region init buffers #region cube var cubeVertexPositionBuffer = new WebGLBuffer(gl); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); var cubesize = 1.0f * 0.05f; var vertices = new[]{ // Front face -cubesize, -cubesize, cubesize, cubesize, -cubesize, cubesize, cubesize, cubesize, cubesize, -cubesize, cubesize, cubesize, // Back face -cubesize, -cubesize, -cubesize, -cubesize, cubesize, -cubesize, cubesize, cubesize, -cubesize, cubesize, -cubesize, -cubesize, // Top face -cubesize, cubesize, -cubesize, -cubesize, cubesize, cubesize, cubesize, cubesize, cubesize, cubesize, cubesize, -cubesize, // Bottom face -cubesize, -cubesize, -cubesize, cubesize, -cubesize, -cubesize, cubesize, -cubesize, cubesize, -cubesize, -cubesize, cubesize, // Right face cubesize, -cubesize, -cubesize, cubesize, cubesize, -cubesize, cubesize, cubesize, cubesize, cubesize, -cubesize, cubesize, // Left face -cubesize, -cubesize, -cubesize, -cubesize, -cubesize, cubesize, -cubesize, cubesize, cubesize, -cubesize, cubesize, -cubesize }; gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); var cubeVertexPositionBuffer_itemSize = 3; var cubeVertexPositionBuffer_numItems = 6 * 6; var squareVertexColorBuffer = new WebGLBuffer(gl); gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexColorBuffer); // 216, 191, 18 var colors = new[]{ 1.0f, 0.6f, 0.0f, 1.0f, // Front face 1.0f, 0.6f, 0.0f, 1.0f, // Front face 1.0f, 0.6f, 0.0f, 1.0f, // Front face 1.0f, 0.6f, 0.0f, 1.0f, // Front face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.8f, 0.4f, 0.0f, 1.0f, // Back face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 0.9f, 0.5f, 0.0f, 1.0f, // Top face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.5f, 0.0f, 1.0f, // Bottom face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Right face 1.0f, 0.8f, 0.0f, 1.0f, // Left face 1.0f, 0.8f, 0.0f, 1.0f, // Left face 1.0f, 0.8f, 0.0f, 1.0f, // Left face 1.0f, 0.8f, 0.0f, 1.0f // Left face }; gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW); var cubeVertexColorBuffer_itemSize = 4; var cubeVertexColorBuffer_numItems = 24; // ELEMENT_ARRAY_BUFFER : WebGLBuffer? // drawElements var cubeVertexIndexBuffer = new WebGLBuffer(gl); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); //var cubeVertexIndices = new UInt16[]{ var cubeVertexIndices = new byte[]{ 0, 1, 2, 0, 2, 3, // Front face 4, 5, 6, 4, 6, 7, // Back face 8, 9, 10, 8, 10, 11, // Top face 12, 13, 14, 12, 14, 15, // Bottom face 16, 17, 18, 16, 18, 19, // Right face 20, 21, 22, 20, 22, 23 // Left face }; // ushort[]? //gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndices, gl.STATIC_DRAW); var cubeVertexIndexBuffer_itemSize = 1; var cubeVertexIndexBuffer_numItems = 36; #endregion #endregion gl.clearColor(0.0f, 0.0f, 0.0f, alpha: 1.0f); gl.enable(gl.DEPTH_TEST); var rWindDelta = 0.0f; var rCubeDelta = 1.0f; if (page != null) { #region WindLeft page.WindLeft.onmousedown += delegate { rWindDelta = -2.0f; }; page.WindLeft.onmouseup += delegate { rWindDelta = 0.0f; }; #endregion #region WindRight page.WindRight.onmousedown += delegate { rWindDelta = 2.0f; }; page.WindRight.onmouseup += delegate { rWindDelta = 0.0f; }; #endregion #region SpeedSlow page.SpeedSlow.onmousedown += delegate { rCubeDelta = 0.1f; }; page.SpeedSlow.onmouseup += delegate { rCubeDelta = 1.0f; }; #endregion #region SpeedFast page.SpeedFast.onmousedown += delegate { rCubeDelta = 4.0f; }; page.SpeedFast.onmouseup += delegate { rCubeDelta = 1.0f; }; #endregion } #region animate var rCube = 0f; var rWind = 0f; var lastTime = 0L; Action animate = delegate { var timeNow = new IDate().getTime(); if (lastTime != 0) { var elapsed = timeNow - lastTime; rCube -= ((75 * elapsed) / 1000.0f) * rCubeDelta; rWind -= ((75 * elapsed) / 1000.0f) * rWindDelta; } lastTime = timeNow; }; #endregion #region degToRad Func<float, float> degToRad = (degrees) => { return degrees * (f)Math.PI / 180f; }; #endregion #region drawScene Action drawScene = delegate { gl.viewport(0, 0, gl_viewportWidth, gl_viewportHeight); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); // glMatrix.mat4.perspective( // 45f, // (float)gl_viewportWidth / (float)gl_viewportHeight, // 0.1f, // 100.0f, // pMatrix //); __mat4.perspective( pMatrix, 45f, (float)gl_viewportWidth / (float)gl_viewportHeight, 0.1f, 100.0f ); __mat4.identity(mvMatrix); //glMatrix.mat4.identity(mvMatrix); __mat4.translate(mvMatrix, mvMatrix, new float[] { -1.5f, 0.0f, -7.0f }); //glMatrix.mat4.translate(mvMatrix, new float[] { -1.5f, 0.0f, -7.0f }); mvPushMatrix(); //glMatrix.mat4.rotate(mvMatrix, degToRad(rWind), new float[] { 0f, 1f, 0f }); __mat4.rotate(mvMatrix, mvMatrix, degToRad(rWind), new float[] { 0, 1f, 0f }); #region DrawFrameworkWingAtX Action<float, float> DrawFrameworkWingAtX = (WingX, WingY) => { #region draw center cube mvPushMatrix(); __mat4.translate(mvMatrix, mvMatrix, new float[] { cubesize * WingX, cubesize * WingY, 0 }); //glMatrix.mat4.translate(mvMatrix, new float[] { cubesize * WingX, cubesize * WingY, 0 }); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, cubeVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexColorBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); setMatrixUniforms(); //gl.drawElements(gl.TRIANGLES, cubeVertexPositionBuffer_numItems, gl.UNSIGNED_SHORT, 0); gl.drawElements(gl.TRIANGLES, cubeVertexPositionBuffer_numItems, gl.UNSIGNED_BYTE, 0); mvPopMatrix(); #endregion }; #endregion #region DrawWingAtX Action<int, int, float, float> DrawWingAtX = (WingX, WingSize, WingRotationMultiplier, WingRotationOffset) => { mvPushMatrix(); __mat4.translate(mvMatrix, mvMatrix, new float[] { cubesize * WingX, 0, 0 }); //glMatrix.mat4.translate(mvMatrix, new float[] { cubesize * WingX, 0, 0 }); if (WingRotationOffset == 0) { DrawFrameworkWingAtX(0, 0); } #region DrawWingPart Action<float> DrawWingPart = PartIndex => { mvPushMatrix(); //glMatrix.mat4.rotate(mvMatrix, degToRad(WingRotationOffset + (rCube * WingRotationMultiplier)), new float[] { 1f, 0f, 0f }); __mat4.rotate(mvMatrix, mvMatrix, degToRad(WingRotationOffset + (rCube * WingRotationMultiplier)), new float[] { 1f, 0f, 0f }); //glMatrix.mat4.translate(mvMatrix, new float[] { 0f, cubesize * PartIndex * 2, 0 }); __mat4.translate(mvMatrix, mvMatrix, new float[] { 0f, cubesize * PartIndex * 2, 0 }); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, cubeVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexColorBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); setMatrixUniforms(); //gl.drawElements(gl.TRIANGLES, cubeVertexPositionBuffer_numItems, gl.UNSIGNED_SHORT, 0); gl.drawElements(gl.TRIANGLES, cubeVertexPositionBuffer_numItems, gl.UNSIGNED_BYTE, 0); mvPopMatrix(); }; #endregion #region DrawWingWithSize Action<int> DrawWingWithSize = length => { for (int i = 4; i < length; i++) { DrawWingPart(i * 1.0f); DrawWingPart(-i * 1.0f); } }; #endregion DrawWingWithSize(WingSize); mvPopMatrix(); }; #endregion var x = 8; DrawFrameworkWingAtX(x - 8, 0); for (int i = 0; i < 24; i++) { DrawFrameworkWingAtX(x - 8, -2.0f * i); } DrawWingAtX(x - 6, 0, 1f, 0); DrawWingAtX(x - 4, 0, 1f, 0); DrawWingAtX(x - 2, 0, 1f, 0); DrawWingAtX(x + 0, 16, 1f, 0); DrawWingAtX(x + 0, 16, 1f, 30); DrawWingAtX(x + 0, 16, 1f, 60); DrawWingAtX(x + 0, 16, 1f, 90); DrawWingAtX(x + 0, 16, 1f, 120); DrawWingAtX(x + 0, 16, 1f, 150); DrawWingAtX(x + 2, 0, 1f, 0); DrawWingAtX(x + 4, 0, 1f, 0); DrawWingAtX(x + 6, 0, 1f, 0); DrawWingAtX(x + 8, 12, 0.4f, 0); DrawWingAtX(x + 8, 12, 0.4f, 60); DrawWingAtX(x + 8, 12, 0.4f, 120); DrawWingAtX(x + 8 + 2, 0, 1f, 0); DrawWingAtX(x + 8 + 4, 0, 1f, 0); DrawWingAtX(x + 8 + 6, 0, 1f, 0); DrawWingAtX(x + 16, 8, 0.3f, 0); DrawWingAtX(x + 16, 8, 0.3f, 90); mvPopMatrix(); #region draw cube on the right to remind where we started //glMatrix.mat4.translate(mvMatrix, new float[] { 3.0f, 2.0f, 0.0f }); __mat4.translate(mvMatrix, mvMatrix, new float[] { 3.0f, 2.0f, 0.0f }); mvPushMatrix(); //glMatrix.mat4.rotate(mvMatrix, degToRad(rCube), new float[] { 1f, 1f, 1f }); __mat4.rotate(mvMatrix, mvMatrix, degToRad(rCube), new float[] { 1f, 1f, 1f }); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexPositionAttribute, cubeVertexPositionBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexColorBuffer); gl.vertexAttribPointer((uint)shaderProgram_vertexColorAttribute, cubeVertexColorBuffer_itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); setMatrixUniforms(); //gl.drawElements(gl.TRIANGLES, cubeVertexPositionBuffer_numItems, gl.UNSIGNED_SHORT, 0); gl.drawElements(gl.TRIANGLES, cubeVertexPositionBuffer_numItems, gl.UNSIGNED_BYTE, 0); mvPopMatrix(); #endregion }; drawScene(); #endregion #region AtResize Action AtResize = delegate { gl_viewportWidth = Native.window.Width; gl_viewportHeight = Native.window.Height; canvas.style.SetLocation(0, 0, gl_viewportWidth, gl_viewportHeight); canvas.width = gl_viewportWidth; canvas.height = gl_viewportHeight; }; Native.window.onresize += e => { AtResize(); }; AtResize(); #endregion #region IsDisposed var IsDisposed = false; this.Dispose = delegate { if (IsDisposed) return; IsDisposed = true; canvas.Orphanize(); }; #endregion #region requestFullscreen Native.document.body.ondblclick += delegate { if (IsDisposed) return; // http://tutorialzine.com/2012/02/enhance-your-website-fullscreen-api/ Native.document.body.requestFullscreen(); }; #endregion //var c = 0; #region tick Native.window.onframe += e => { if (IsDisposed) return; //c++; // frameID Native.document.title = "" + e.counter; drawScene(); animate(); }; #endregion if (page != null) page.Mission.Orphanize().AttachToDocument().style.SetLocation(left: size - 56, top: 16); }
/// <summary> /// This is a javascript application. /// </summary> /// <param name="page">HTML document rendered by the web server which can now be enhanced.</param> public Application(IDefault page = null) { #region += Launched chrome.app.window //Error CS0656 Missing compiler required member 'Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create' ChromeWebGLFrameBufferToSquare X:\jsc.svn\examples\javascript\chrome\apps\WebGL\ChromeWebGLFrameBufferToSquare\ChromeWebGLFrameBufferToSquare\Application.cs 51 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 //Z:\jsc.svn\examples\javascript\WebGLLesson01\WebGLLesson01\Application.cs(48,13): error CS0121: The call is ambiguous between the following methods or properties: // 'ScriptCoreLib.Extensions.LinqExtensions.With<ScriptCoreLib.JavaScript.DOM.HTML.IHTMLScript>(ScriptCoreLib.JavaScript.DOM.HTML.IHTMLScript, System.Action<ScriptCoreLib.JavaScript.DOM.HTML.IHTMLScript>)' and // 'ScriptCoreLib.Extensions.LinqExtensions.With<ScriptCoreLib.JavaScript.DOM.HTML.IHTMLScript>(ScriptCoreLib.JavaScript.DOM.HTML.IHTMLScript, System.Action<ScriptCoreLib.JavaScript.DOM.HTML.IHTMLScript>)' // works for IE11 //var size = 512; //var size = 256; //var size = 96; // size wont matter? always rendered var size = 16; var rttFramebuffer_width = 128; var rttFramebuffer_height = 128; var gl = new WebGLRenderingContext(); var canvas = gl.canvas.AttachToDocument(); Native.document.body.style.overflow = IStyle.OverflowEnum.hidden; canvas.style.SetLocation(0, 0, size, size); canvas.width = size; canvas.height = size; var gl_viewportWidth = size; var gl_viewportHeight = size; #region createShader // dont we have a better api already? Func<ScriptCoreLib.GLSL.Shader, WebGLShader> createShader = (src) => { var shader = gl.createShader(src); // verify if (gl.getShaderParameter(shader, gl.COMPILE_STATUS) == null) { Native.window.alert("error in SHADER:\n" + gl.getShaderInfoLog(shader)); throw new InvalidOperationException("shader failed"); return null; } return shader; }; #endregion var vs = createShader(new GeometryVertexShader()); var fs = createShader(new GeometryFragmentShader()); var shaderProgram = new WebGLProgram(gl); gl.attachShader(shaderProgram, vs); gl.attachShader(shaderProgram, fs); gl.linkProgram(shaderProgram); var mvMatrix = glMatrix.mat4.create(); var pMatrix = glMatrix.mat4.create(); var vec3aVertexPositionBuffer = new WebGLBuffer(gl); var vec2aTextureCoordBuffer = new WebGLBuffer(gl); gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); gl.enable(gl.DEPTH_TEST); #region initTextureFramebuffer var xWebGLFramebuffer = new WebGLFramebuffer(gl); gl.bindFramebuffer(gl.FRAMEBUFFER, xWebGLFramebuffer); // generateMipmap: level 0 not power of 2 or not all the same size //var rttFramebuffer_width = canvas.width; // WebGL: INVALID_OPERATION: generateMipmap: level 0 not power of 2 or not all the same size var xWebGLTexture = new WebGLTexture(gl); gl.bindTexture(gl.TEXTURE_2D, xWebGLTexture); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, (int)gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, (int)gl.LINEAR_MIPMAP_NEAREST); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, rttFramebuffer_width, rttFramebuffer_height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); gl.generateMipmap(gl.TEXTURE_2D); var xWebGLRenderbuffer = new WebGLRenderbuffer(gl); gl.bindRenderbuffer(gl.RENDERBUFFER, xWebGLRenderbuffer); gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, rttFramebuffer_width, rttFramebuffer_height); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, xWebGLTexture, 0); gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, xWebGLRenderbuffer); gl.bindTexture(gl.TEXTURE_2D, null); gl.bindRenderbuffer(gl.RENDERBUFFER, null); gl.bindFramebuffer(gl.FRAMEBUFFER, null); #endregion var pass = new ChromeShaderToyColumns.Library.ShaderToy.EffectPass( gl: gl, precission: ChromeShaderToyColumns.Library.ShaderToy.DetermineShaderPrecission(gl), supportDerivatives: gl.getExtension("OES_standard_derivatives") != null ); pass.MakeHeader_Image(); pass.NewShader_Image( new ChromeShaderToyColumns.Shaders.ProgramFragmentShader() ); var sw = Stopwatch.StartNew(); var vbo = new WebGLBuffer(gl); Native.window.onframe += e => { // can we run it in VR as HUD? // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150706 #region FRAMEBUFFER gl.bindFramebuffer(gl.FRAMEBUFFER, xWebGLFramebuffer); //// http://stackoverflow.com/questions/20362023/webgl-why-does-transparent-canvas-show-clearcolor-color-component-when-alpha-is gl.clearColor(1, 1, 0, 1.0f); gl.viewport(0, 0, rttFramebuffer_width, rttFramebuffer_height); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); #region Paint_Image ChromeShaderToyColumns.Library.ShaderToy.EffectPass.Paint_ImageDelegate Paint_Image = (time, mouseOriX, mouseOriY, mousePosX, mousePosY, zoom) => { var mProgram = pass.xCreateShader.mProgram; var xres = rttFramebuffer_width; var yres = rttFramebuffer_height; #region Paint_Image //new IHTMLPre { "enter Paint_Image" }.AttachToDocument(); // this is enough to do pip to bottom left, no need to adjust vertex positions even? //gl.viewport(0, 0, (int)xres, (int)yres); // useProgram: program not valid gl.useProgram(mProgram); // uniform4fv var mouse = new[] { mousePosX, mousePosY, mouseOriX, mouseOriY }; // X:\jsc.svn\examples\glsl\future\GLSLShaderToyPip\GLSLShaderToyPip\Application.cs //gl.getUniformLocation(mProgram, "fZoom").With(fZoom => gl.uniform1f(fZoom, zoom)); var l2 = gl.getUniformLocation(mProgram, "iGlobalTime"); if (l2 != null) gl.uniform1f(l2, time); var l3 = gl.getUniformLocation(mProgram, "iResolution"); if (l3 != null) gl.uniform3f(l3, xres, yres, 1.0f); var l4 = gl.getUniformLocation(mProgram, "iMouse"); if (l4 != null) gl.uniform4fv(l4, mouse); //var l7 = gl.getUniformLocation(this.mProgram, "iDate"); if (l7 != null) gl.uniform4fv(l7, dates); //var l9 = gl.getUniformLocation(this.mProgram, "iSampleRate"); if (l9 != null) gl.uniform1f(l9, this.mSampleRate); var ich0 = gl.getUniformLocation(mProgram, "iChannel0"); if (ich0 != null) gl.uniform1i(ich0, 0); var ich1 = gl.getUniformLocation(mProgram, "iChannel1"); if (ich1 != null) gl.uniform1i(ich1, 1); var ich2 = gl.getUniformLocation(mProgram, "iChannel2"); if (ich2 != null) gl.uniform1i(ich2, 2); var ich3 = gl.getUniformLocation(mProgram, "iChannel3"); if (ich3 != null) gl.uniform1i(ich3, 3); // what if there are other textures too? // X:\jsc.svn\examples\javascript\chrome\apps\WebGL\ChromeWebGLFrameBuffer\ChromeWebGLFrameBuffer\Application.cs //for (var i = 0; i < mInputs.Length; i++) //{ // var inp = mInputs[i]; // gl.activeTexture((uint)(gl.TEXTURE0 + i)); // if (inp == null) // { // gl.bindTexture(gl.TEXTURE_2D, null); // } //} var times = new[] { 0.0f, 0.0f, 0.0f, 0.0f }; var l5 = gl.getUniformLocation(mProgram, "iChannelTime"); if (l5 != null) gl.uniform1fv(l5, times); var resos = new float[12] { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; var l8 = gl.getUniformLocation(mProgram, "iChannelResolution"); if (l8 != null) gl.uniform3fv(l8, resos); // using ? var vec2pos = (uint)gl.getAttribLocation(mProgram, "pos"); //gl.bindBuffer(gl.ARRAY_BUFFER, quadVBO); gl.bindBuffer(gl.ARRAY_BUFFER, vbo); #region vertices float left = -1.0f; // y reversed? float bottom = -1.0f; float right = 1.0f; float top = 1.0f; var fvertices = new float[] { // left top left, bottom, // right top //right, -1.0f, right, bottom, // left bottom left, top, // right top //right, -1.0f, right, bottom, // right bottom //right, 1.0f, right, top, // left bottom left,top }; var vertices = new Float32Array(fvertices); #endregion gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); gl.vertexAttribPointer(vec2pos, 2, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(vec2pos); // GL ERROR :GL_INVALID_OPERATION : glDrawArrays: attempt to render with no buffer attached to enabled attribute 1 gl.drawArrays(gl.TRIANGLES, 0, 6); // first frame is now visible gl.disableVertexAttribArray(vec2pos); gl.bindBuffer(gl.ARRAY_BUFFER, null); #endregion //mFrame++; }; #endregion Paint_Image( sw.ElapsedMilliseconds / 1000.0f, 0, 0, 0, 0 ); gl.flush(); //// INVALID_OPERATION: generateMipmap: level 0 not power of 2 or not all the same size gl.bindTexture(gl.TEXTURE_2D, xWebGLTexture); gl.generateMipmap(gl.TEXTURE_2D); gl.bindTexture(gl.TEXTURE_2D, null); gl.bindFramebuffer(gl.FRAMEBUFFER, null); #endregion gl.clearColor(0, 0, 1, 1.0f); gl.viewport(0, 0, gl.canvas.width, gl.canvas.height); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); glMatrix.mat4.perspective(45f, (float)gl_viewportWidth / (float)gl_viewportHeight, 0.1f, 120.0f, pMatrix); glMatrix.mat4.identity(mvMatrix); glMatrix.mat4.translate(mvMatrix, new float[] { -1.5f + (f)Math.Cos( sw.ElapsedMilliseconds //slow it down *0.001f ) , 0.0f, -15.0f }); //glMatrix.mat4.translate(mvMatrix, new float[] { 3.0f, 0.0f, 0.0f }); gl.useProgram(shaderProgram); // X:\jsc.svn\examples\javascript\WebGL\WebGLLesson05\WebGLLesson05\Application.cs gl.uniformMatrix4fv(gl.getUniformLocation(shaderProgram, "uPMatrix"), false, pMatrix); gl.uniformMatrix4fv(gl.getUniformLocation(shaderProgram, "uMVMatrix"), false, mvMatrix); // GL_INVALID_OPERATION : glDrawArrays: attempt to access out of range vertices in attribute 1 for (int ihalf = 0; ihalf < 2; ihalf++) { #region vec2aTextureCoord var vec2aTextureCoord = gl.getAttribLocation(shaderProgram, "aTextureCoord"); gl.bindBuffer(gl.ARRAY_BUFFER, vec2aTextureCoordBuffer); // http://iphonedevelopment.blogspot.com/2009/05/opengl-es-from-ground-up-part-6_25.html var textureCoords = new float[]{ // Front face 0.0f, 0.0f, 0.0f, -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, }; if (ihalf % 2 == 0) { textureCoords = new[]{ 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, }; } gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoords), gl.STATIC_DRAW); gl.vertexAttribPointer((uint)vec2aTextureCoord, 2, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray((uint)vec2aTextureCoord); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, xWebGLTexture); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, (int)gl.NEAREST); gl.uniform1i(gl.getUniformLocation(shaderProgram, "uSampler"), 0); #endregion #region aVertexPosition var vec3aVertexPosition = gl.getAttribLocation(shaderProgram, "aVertexPosition"); gl.bindBuffer(gl.ARRAY_BUFFER, vec3aVertexPositionBuffer); var rsize = 4f; var vec3vertices = new[]{ rsize, rsize, 0.0f, rsize, -rsize, 0.0f, -rsize, -rsize, 0.0f, //-4.0f, -4.0f, 0.0f, //-4, 4f, 0.0f, //4.0f, 4.0f, 0.0f, }; if (ihalf % 2 == 0) { vec3vertices = new[]{ -rsize, -rsize, 0.0f, -rsize, rsize, 0.0f, rsize, rsize, 0.0f, }; } gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vec3vertices), gl.STATIC_DRAW); gl.vertexAttribPointer((uint)vec3aVertexPosition, 3, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray((uint)vec3aVertexPosition); #endregion var vec3vertices_numItems = vec3vertices.Length / 3; //gl.drawArrays(gl.TRIANGLE_STRIP, 0, vertices.Length / 3); gl.drawArrays(gl.TRIANGLE_STRIP, 0, vec3vertices_numItems); } }; #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 }