Exemplo n.º 1
0
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            Closed += ShaderTest_Closed;

            gl3dcontroller = new Controller3D();
            gl3dcontroller.MatrixCalc.PerspectiveNearZDistance = 1f;
            gl3dcontroller.MatrixCalc.PerspectiveFarZDistance  = 100000f;
            gl3dcontroller.ZoomDistance          = 5000F;
            gl3dcontroller.PosCamera.ZoomMin     = 0.1f;
            gl3dcontroller.PosCamera.ZoomScaling = 1.1f;
            gl3dcontroller.YHoldMovement         = true;
            gl3dcontroller.PaintObjects          = ControllerDraw;

            gl3dcontroller.KeyboardTravelSpeed = (ms, eyedist) =>
            {
                return((float)ms * 1.0f * Math.Min(eyedist / 1000, 10));
            };

            gl3dcontroller.MatrixCalc.InPerspectiveMode = true;
            gl3dcontroller.Start(glwfc, new Vector3(0, 0, 10000), new Vector3(140.75f, 0, 0), 0.5F);

            items.Add(new GLMatrixCalcUniformBlock(), "MCUB");      // create a matrix uniform block

            int front = -20000, back = front + 90000, left = -45000, right = left + 90000, vsize = 2000;

            boundingbox = new Vector4[]
            {
                new Vector4(left, -vsize, front, 1),
                new Vector4(left, vsize, front, 1),
                new Vector4(right, vsize, front, 1),
                new Vector4(right, -vsize, front, 1),

                new Vector4(left, -vsize, back, 1),
                new Vector4(left, vsize, back, 1),
                new Vector4(right, vsize, back, 1),
                new Vector4(right, -vsize, back, 1),
            };

            Vector4[] displaylines = new Vector4[]
            {
                new Vector4(left, -vsize, front, 1), new Vector4(left, +vsize, front, 1),
                new Vector4(left, +vsize, front, 1), new Vector4(right, +vsize, front, 1),
                new Vector4(right, +vsize, front, 1), new Vector4(right, -vsize, front, 1),
                new Vector4(right, -vsize, front, 1), new Vector4(left, -vsize, front, 1),

                new Vector4(left, -vsize, back, 1), new Vector4(left, +vsize, back, 1),
                new Vector4(left, +vsize, back, 1), new Vector4(right, +vsize, back, 1),
                new Vector4(right, +vsize, back, 1), new Vector4(right, -vsize, back, 1),
                new Vector4(right, -vsize, back, 1), new Vector4(left, -vsize, back, 1),

                new Vector4(left, -vsize, front, 1), new Vector4(left, -vsize, back, 1),
                new Vector4(left, +vsize, front, 1), new Vector4(left, +vsize, back, 1),
                new Vector4(right, -vsize, front, 1), new Vector4(right, -vsize, back, 1),
                new Vector4(right, +vsize, front, 1), new Vector4(right, +vsize, back, 1),
            };

            {
                items.Add(new GLFixedShader(System.Drawing.Color.Yellow), "LINEYELLOW");
                GLRenderState rl = GLRenderState.Lines(1);
                rObjects.Add(items.Shader("LINEYELLOW"), GLRenderableItem.CreateVector4(items, PrimitiveType.Lines, rl, displaylines));
            }


            {
                items.Add(new GLTexture2D(Properties.Resources.golden, SizedInternalFormat.Rgba8), "solmarker");
                items.Add(new GLTexturedShaderObjectTranslation(), "TEX");
                GLRenderState rq = GLRenderState.Quads(cullface: false);
                rObjects.Add(items.Shader("TEX"),
                             GLRenderableItem.CreateVector4Vector2(items, PrimitiveType.Quads, rq,
                                                                   GLShapeObjectFactory.CreateQuad(1000.0f, 1000.0f, new Vector3(0, 0, 0)), GLShapeObjectFactory.TexQuadCW,
                                                                   new GLRenderDataTranslationRotationTexture(items.Tex("solmarker"), new Vector3(0, 1000, 0))
                                                                   ));
                rObjects.Add(items.Shader("TEX"),
                             GLRenderableItem.CreateVector4Vector2(items, PrimitiveType.Quads, rq,
                                                                   GLShapeObjectFactory.CreateQuad(1000.0f, 1000.0f, new Vector3(0, 0, 0)), GLShapeObjectFactory.TexQuadCW,
                                                                   new GLRenderDataTranslationRotationTexture(items.Tex("solmarker"), new Vector3(0, -1000, 0))
                                                                   ));
                items.Add(new GLTexture2D(Properties.Resources.dotted, SizedInternalFormat.Rgba8), "sag");
                rObjects.Add(items.Shader("TEX"),
                             GLRenderableItem.CreateVector4Vector2(items, PrimitiveType.Quads, rq,
                                                                   GLShapeObjectFactory.CreateQuad(1000.0f, 1000.0f, new Vector3(0, 0, 0)), GLShapeObjectFactory.TexQuadCW,
                                                                   new GLRenderDataTranslationRotationTexture(items.Tex("sag"), new Vector3(25.2f, 2000, 25899))
                                                                   ));
                rObjects.Add(items.Shader("TEX"),
                             GLRenderableItem.CreateVector4Vector2(items, PrimitiveType.Quads, rq,
                                                                   GLShapeObjectFactory.CreateQuad(1000.0f, 1000.0f, new Vector3(0, 0, 0)), GLShapeObjectFactory.TexQuadCW,
                                                                   new GLRenderDataTranslationRotationTexture(items.Tex("sag"), new Vector3(25.2f, -2000, 25899))
                                                                   ));
                items.Add(new GLTexture2D(Properties.Resources.dotted2, SizedInternalFormat.Rgba8), "bp");
                rObjects.Add(items.Shader("TEX"),
                             GLRenderableItem.CreateVector4Vector2(items, PrimitiveType.Quads, rq,
                                                                   GLShapeObjectFactory.CreateQuad(1000.0f, 1000.0f, new Vector3(0, 0, 0)), GLShapeObjectFactory.TexQuadCW,
                                                                   new GLRenderDataTranslationRotationTexture(items.Tex("bp"), new Vector3(-1111f, 0, 65269))
                                                                   ));
            }

            if (false) // galaxy
            {
                volumetricblock = new GLVolumetricUniformBlock();
                items.Add(volumetricblock, "VB");

                int         sc      = 1;
                GLTexture3D noise3d = new GLTexture3D(1024 * sc, 64 * sc, 1024 * sc, OpenTK.Graphics.OpenGL4.SizedInternalFormat.R32f);         // red channel only
                items.Add(noise3d, "Noise");
                ComputeShaderNoise3D csn = new ComputeShaderNoise3D(noise3d.Width, noise3d.Height, noise3d.Depth, 128 * sc, 16 * sc, 128 * sc); // must be a multiple of localgroupsize in csn
                csn.StartAction += (A, m) => { noise3d.BindImage(3); };
                csn.Run();                                                                                                                      // compute noise

                GLTexture1D gaussiantex = new GLTexture1D(1024, OpenTK.Graphics.OpenGL4.SizedInternalFormat.R32f);                              // red channel only
                items.Add(gaussiantex, "Gaussian");

                // set centre=width, higher widths means more curve, higher std dev compensate.
                // fill the gaussiantex with data
                ComputeShaderGaussian gsn = new ComputeShaderGaussian(gaussiantex.Width, 2.0f, 2.0f, 1.4f, 4);
                gsn.StartAction += (A, m) => { gaussiantex.BindImage(4); };
                gsn.Run();      // compute noise

                GL.MemoryBarrier(MemoryBarrierFlags.AllBarrierBits);

                //float[] gdata = gaussiantex.GetTextureImageAsFloats(OpenTK.Graphics.OpenGL4.PixelFormat.Red); // read back check
                //for( int i = 0; i < gdata.Length; i++  )
                //{
                //    double v = ((float)i / gdata.Length-0.5)*2*2;
                //    double r = ObjectExtensionsNumbersBool.GaussianDist(v, 2, 1.4);
                // //   System.Diagnostics.Debug.WriteLine(i + ":" + gdata[i] + ": " +  r);
                //}

                // load one upside down and horz flipped, because the volumetric co-ords are 0,0,0 bottom left, 1,1,1 top right
                GLTexture2D galtex = new GLTexture2D(Properties.Resources.Galaxy_L180, SizedInternalFormat.Rgba8);
                items.Add(galtex, "gal");
                GalaxyShader gs = new GalaxyShader();
                items.Add(gs, "Galaxy");
                // bind the galaxy texture, the 3dnoise, and the gaussian 1-d texture for the shader
                gs.StartAction = (a, m) => { galtex.Bind(1); noise3d.Bind(3); gaussiantex.Bind(4); };      // shader requires these, so bind using shader

                GLRenderState rt = GLRenderState.Tri();
                galaxy = GLRenderableItem.CreateNullVertex(PrimitiveType.Points, rt);   // no vertexes, all data from bound volumetric uniform, no instances as yet
                rObjects.Add(items.Shader("Galaxy"), galaxy);
            }

            if (true) // star points
            {
                int    gran = 8;
                Bitmap img  = Properties.Resources.Galaxy_L180;
                Bitmap heat = img.Function(img.Width / gran, img.Height / gran, mode: GLOFC.Utils.BitMapHelpers.BitmapFunction.HeatMap);
                heat.Save(@"c:\code\heatmap.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);

                Random rnd = new Random(23);

                GLBuffer buf = new GLBuffer(16 * 500000); // since RND is fixed, should get the same number every time.
                buf.StartWrite(0);                        // get a ptr to the whole schebang

                int xcw = (right - left) / heat.Width;
                int zch = (back - front) / heat.Height;

                int points = 0;

                for (int x = 0; x < heat.Width; x++)
                {
                    for (int z = 0; z < heat.Height; z++)
                    {
                        int i  = heat.GetPixel(x, z).R;
                        int ii = i * i * i;
                        if (ii > 32 * 32 * 32)
                        {
                            int gx = left + x * xcw;
                            int gz = front + z * zch;

                            float  dx = (float)Math.Abs(gx) / 45000;
                            float  dz = (float)Math.Abs(25889 - gz) / 45000;
                            double d  = Math.Sqrt(dx * dx + dz * dz); // 0 - 0.1412
                            d = 1 - d;                                // 1 = centre, 0 = unit circle
                            d = d * 2 - 1;                            // -1 to +1
                            double dist = ObjectExtensionsNumbersBool.GaussianDist(d, 1, 1.4);

                            int c = Math.Min(Math.Max(ii / 140000, 0), 20);

                            dist *= 2000;

                            GLPointsFactory.RandomStars4(buf, c, gx, gx + xcw, gz, gz + zch, (int)dist, (int)-dist, rnd, w: i);
                            points += c;
                            System.Diagnostics.Debug.Assert(points < buf.Length / 16);
                        }
                    }
                }

                buf.StopReadWrite();

                items.Add(new GalaxyStarDots(), "SD");
                GLRenderState rp = GLRenderState.Points(1);
                rp.DepthTest = false;
                rObjects.Add(items.Shader("SD"),
                             GLRenderableItem.CreateVector4(items, PrimitiveType.Points, rp, buf, points));
                System.Diagnostics.Debug.WriteLine("Stars " + points);
            }

            if (true)  // point sprite
            {
                items.Add(new GLTexture2D(Properties.Resources.StarFlare2, SizedInternalFormat.Rgba8), "lensflare");
                items.Add(new GLPointSpriteShader(items.Tex("lensflare"), 64, 40), "PS1");
                var p = GLPointsFactory.RandomStars4(1000, 0, 25899, 10000, 1000, -1000);

                GLRenderState rps = GLRenderState.PointSprites();
                rps.DepthTest = false;

                rObjects.Add(items.Shader("PS1"),
                             GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Points, rps, p, new Color4[] { Color.White }));
            }

            {
                items.Add(new DynamicGridVertexShader(Color.Cyan), "PLGRIDVertShader");
                items.Add(new GLPLFragmentShaderVSColor(), "PLGRIDFragShader");

                GLRenderState rl = GLRenderState.Lines(1);
                rl.DepthTest = false;

                items.Add(new GLShaderPipeline(items.PLShader("PLGRIDVertShader"), items.PLShader("PLGRIDFragShader")), "DYNGRID");
                rObjects.Add(items.Shader("DYNGRID"), "DYNGRIDRENDER", GLRenderableItem.CreateNullVertex(PrimitiveType.Lines, rl, drawcount: 2));
            }


            {
                items.Add(new DynamicGridCoordVertexShader(), "PLGRIDBitmapVertShader");
                items.Add(new GLPLFragmentShaderTexture2DIndexed(0), "PLGRIDBitmapFragShader");     // binding

                GLRenderState rl = GLRenderState.Tri(cullface: false);
                rl.DepthTest = false;

                gridtexcoords = new GLTexture2DArray();
                items.Add(gridtexcoords, "PLGridBitmapTextures");

                GLShaderPipeline sp = new GLShaderPipeline(items.PLShader("PLGRIDBitmapVertShader"), items.PLShader("PLGRIDBitmapFragShader"));

                items.Add(sp, "DYNGRIDBitmap");

                rObjects.Add(items.Shader("DYNGRIDBitmap"), "DYNGRIDBitmapRENDER", GLRenderableItem.CreateNullVertex(PrimitiveType.TriangleStrip, rl, drawcount: 4, instancecount: 9));
            }
        }
Exemplo n.º 2
0
        public void Start(GLOFC.WinForm.GLWinFormControl glwfc, GalacticMapping edsmmapping, GalacticMapping eliteregions)
        {
            this.glwfc        = glwfc;
            this.edsmmapping  = edsmmapping;
            this.elitemapping = eliteregions;

            hptimer.Start();

            items.Add(new GLMatrixCalcUniformBlock(), "MCUB");     // create a matrix uniform block

            int lyscale = 1;
            int front = -20000 / lyscale, back = front + 90000 / lyscale, left = -45000 / lyscale, right = left + 90000 / lyscale, vsize = 2000 / lyscale;

            if (false)     // debug bounding box
            {
                Vector4[] displaylines = new Vector4[]
                {
                    new Vector4(left, -vsize, front, 1), new Vector4(left, +vsize, front, 1),
                    new Vector4(left, +vsize, front, 1), new Vector4(right, +vsize, front, 1),
                    new Vector4(right, +vsize, front, 1), new Vector4(right, -vsize, front, 1),
                    new Vector4(right, -vsize, front, 1), new Vector4(left, -vsize, front, 1),

                    new Vector4(left, -vsize, back, 1), new Vector4(left, +vsize, back, 1),
                    new Vector4(left, +vsize, back, 1), new Vector4(right, +vsize, back, 1),
                    new Vector4(right, +vsize, back, 1), new Vector4(right, -vsize, back, 1),
                    new Vector4(right, -vsize, back, 1), new Vector4(left, -vsize, back, 1),

                    new Vector4(left, -vsize, front, 1), new Vector4(left, -vsize, back, 1),
                    new Vector4(left, +vsize, front, 1), new Vector4(left, +vsize, back, 1),
                    new Vector4(right, -vsize, front, 1), new Vector4(right, -vsize, back, 1),
                    new Vector4(right, +vsize, front, 1), new Vector4(right, +vsize, back, 1),
                };

                GLRenderState rl = GLRenderState.Lines(1);

                items.Add(new GLShaderPipeline(new GLPLVertexShaderWorldCoord(), new GLPLFragmentShaderFixedColor(Color.Yellow)), "LINEYELLOW");
                rObjects.Add(items.Shader("LINEYELLOW"),
                             GLRenderableItem.CreateVector4(items, PrimitiveType.Lines, rl, displaylines));

                items.Add(new GLColorShaderWorld(), "COS-1L");

                float h = 0;

                int   dist = 1000 / lyscale;
                Color cr   = Color.FromArgb(100, Color.White);
                rObjects.Add(items.Shader("COS-1L"),    // horizontal
                             GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Lines, rl,
                                                                  GLShapeObjectFactory.CreateLines(new Vector3(left, h, front), new Vector3(left, h, back), new Vector3(dist, 0, 0), (back - front) / dist + 1),
                                                                  new OpenTK.Graphics.Color4[] { cr })
                             );

                rObjects.Add(items.Shader("COS-1L"),
                             GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Lines, rl,
                                                                  GLShapeObjectFactory.CreateLines(new Vector3(left, h, front), new Vector3(right, h, front), new Vector3(0, 0, dist), (right - left) / dist + 1),
                                                                  new OpenTK.Graphics.Color4[] { cr })
                             );

                rObjects.Add(new GLOperationClearDepthBuffer());
            }

            int ctrlo = 2048 | 32 | 64;

            ctrlo = -1;

            if ((ctrlo & 1) != 0) // galaxy
            {
                volumetricboundingbox = new Vector4[]
                {
                    new Vector4(left, -vsize, front, 1),
                    new Vector4(left, vsize, front, 1),
                    new Vector4(right, vsize, front, 1),
                    new Vector4(right, -vsize, front, 1),

                    new Vector4(left, -vsize, back, 1),
                    new Vector4(left, vsize, back, 1),
                    new Vector4(right, vsize, back, 1),
                    new Vector4(right, -vsize, back, 1),
                };


                const int gnoisetexbinding = 3;     //tex bindings are attached per shaders so are not global
                const int gdisttexbinding  = 4;
                const int galtexbinding    = 1;

                volumetricblock = new GLVolumetricUniformBlock(volumenticuniformblock);
                items.Add(volumetricblock, "VB");

                int         sc      = 1;
                GLTexture3D noise3d = new GLTexture3D(1024 * sc, 64 * sc, 1024 * sc, OpenTK.Graphics.OpenGL4.SizedInternalFormat.R32f);                           // red channel only
                items.Add(noise3d, "Noise");
                ComputeShaderNoise3D csn = new ComputeShaderNoise3D(noise3d.Width, noise3d.Height, noise3d.Depth, 128 * sc, 16 * sc, 128 * sc, gnoisetexbinding); // must be a multiple of localgroupsize in csn
                csn.StartAction += (A, m) => { noise3d.BindImage(gnoisetexbinding); };
                csn.Run();                                                                                                                                        // compute noise
                csn.Dispose();

                GLTexture1D gaussiantex = new GLTexture1D(1024, OpenTK.Graphics.OpenGL4.SizedInternalFormat.R32f); // red channel only
                items.Add(gaussiantex, "Gaussian");

                // set centre=width, higher widths means more curve, higher std dev compensate.
                // fill the gaussiantex with data
                ComputeShaderGaussian gsn = new ComputeShaderGaussian(gaussiantex.Width, 2.0f, 2.0f, 1.4f, gdisttexbinding);
                gsn.StartAction += (A, m) => { gaussiantex.BindImage(gdisttexbinding); };
                gsn.Run();      // compute noise
                gsn.Dispose();

                GL.MemoryBarrier(MemoryBarrierFlags.AllBarrierBits);

                // load one upside down and horz flipped, because the volumetric co-ords are 0,0,0 bottom left, 1,1,1 top right
                GLTexture2D galtex = new GLTexture2D(Properties.Resources.Galaxy_L180, SizedInternalFormat.Rgba8);
                items.Add(galtex, "galtex");
                galaxyshader = new GalaxyShader(volumenticuniformblock, galtexbinding, gnoisetexbinding, gdisttexbinding);
                items.Add(galaxyshader, "Galaxy-sh");
                // bind the galaxy texture, the 3dnoise, and the gaussian 1-d texture for the shader
                galaxyshader.StartAction += (a, m) => { galtex.Bind(galtexbinding); noise3d.Bind(gnoisetexbinding); gaussiantex.Bind(gdisttexbinding); };      // shader requires these, so bind using shader

                GLRenderState rt = GLRenderState.Tri();
                galaxyrenderable = GLRenderableItem.CreateNullVertex(OpenTK.Graphics.OpenGL4.PrimitiveType.Points, rt);   // no vertexes, all data from bound volumetric uniform, no instances as yet
                rObjects.Add(galaxyshader, "galshader", galaxyrenderable);
            }

            if ((ctrlo & 2) != 0)
            {
                var corr = new GalMapRegions.ManualCorrections[] {          // nerf the centeroid position slightly
                    new GalMapRegions.ManualCorrections("The Galactic Aphelion", y: -2000),
                    new GalMapRegions.ManualCorrections("The Abyss", y: +3000),
                    new GalMapRegions.ManualCorrections("Eurus", y: -3000),
                    new GalMapRegions.ManualCorrections("The Perseus Transit", x: -3000, y: -3000),
                    new GalMapRegions.ManualCorrections("Zephyrus", x: 0, y: 2000),
                };

                edsmgalmapregions = new GalMapRegions();
                edsmgalmapregions.CreateObjects("edsmregions", items, rObjects, edsmmapping, 8000, corr: corr);
            }

            if ((ctrlo & 4) != 0)
            {
                elitemapregions = new GalMapRegions();
                elitemapregions.CreateObjects("eliteregions", items, rObjects, eliteregions, 8000);
                EliteRegionsEnable = false;
            }

            if ((ctrlo & 8) != 0)
            {
                int    gran = 8;
                Bitmap img  = Properties.Resources.Galaxy_L180;
                Bitmap heat = img.Function(img.Width / gran, img.Height / gran, mode: GLOFC.Utils.BitMapHelpers.BitmapFunction.HeatMap);
                heat.Save(@"c:\code\heatmap.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);

                Random rnd = new Random(23);

                GLBuffer buf = items.NewBuffer(16 * 350000, false); // since RND is fixed, should get the same number every time.
                buf.StartWrite(0);                                  // get a ptr to the whole schebang

                int xcw = (right - left) / heat.Width;
                int zch = (back - front) / heat.Height;

                int points = 0;

                for (int x = 0; x < heat.Width; x++)
                {
                    for (int z = 0; z < heat.Height; z++)
                    {
                        int i = heat.GetPixel(x, z).R;
                        if (i > 32)
                        {
                            int gx = left + x * xcw;
                            int gz = front + z * zch;

                            float  dx = (float)Math.Abs(gx) / 45000;
                            float  dz = (float)Math.Abs(25889 - gz) / 45000;
                            double d  = Math.Sqrt(dx * dx + dz * dz); // 0 - 0.1412
                            d = 1 - d;                                // 1 = centre, 0 = unit circle
                            d = d * 2 - 1;                            // -1 to +1
                            double dist = ObjectExtensionsNumbersBool.GaussianDist(d, 1, 1.4);

                            int c = Math.Min(Math.Max(i * i * i / 120000, 1), 40);
                            //int c = Math.Min(Math.Max(i * i * i / 24000000, 1), 40);

                            dist *= 2000 / lyscale;
                            //System.Diagnostics.Debug.WriteLine("{0} {1} : dist {2} c {3}", x, z, dist, c);
                            //System.Diagnostics.Debug.Write(c);
                            GLPointsFactory.RandomStars4(buf, c, gx, gx + xcw, gz, gz + zch, (int)dist, (int)-dist, rnd, w: 0.8f);
                            points += c;
                            System.Diagnostics.Debug.Assert(points < buf.Length / 16);
                        }
                    }
                    //System.Diagnostics.Debug.WriteLine(".");
                }

                buf.StopReadWrite();

                stardots = new GalaxyStarDots();
                items.Add(stardots);
                GLRenderState rc = GLRenderState.Points(1);
                rc.DepthTest = false; // note, if this is true, there is a wierd different between left and right in view.. not sure why
                rObjects.Add(stardots, "stardots", GLRenderableItem.CreateVector4(items, OpenTK.Graphics.OpenGL4.PrimitiveType.Points, rc, buf, points));
                System.Diagnostics.Debug.WriteLine("Stars " + points);
            }

            rObjects.Add(new GLOperationClearDepthBuffer()); // clear depth buffer and now use full depth testing on the rest

            if ((ctrlo & 16) != 0)
            {
                items.Add(new GLTexture2D(Properties.Resources.StarFlare2, SizedInternalFormat.Rgba8), "lensflare");
                items.Add(new GLPointSpriteShader(items.Tex("lensflare"), 64, 40), "PS");
                var p = GLPointsFactory.RandomStars4(1000, 0, 25899 / lyscale, 10000 / lyscale, 1000 / lyscale, -1000 / lyscale);

                GLRenderState rps = GLRenderState.PointSprites();

                rObjects.Add(items.Shader("PS"), "starsprites", GLRenderableItem.CreateVector4Color4(items, OpenTK.Graphics.OpenGL4.PrimitiveType.Points, rps, p, new Color4[] { Color.White }));
            }

            if ((ctrlo & 32) != 0)
            {
                gridvertshader = new DynamicGridVertexShader(Color.Cyan);
                //items.Add(gridvertshader, "PLGRIDVertShader");
                var frag = new GLPLFragmentShaderVSColor();
                //items.Add(frag, "PLGRIDFragShader");

                GLRenderState rl = GLRenderState.Lines(1);

                items.Add(new GLShaderPipeline(gridvertshader, frag), "DYNGRID");

                gridrenderable = GLRenderableItem.CreateNullVertex(OpenTK.Graphics.OpenGL4.PrimitiveType.Lines, rl, drawcount: 2);

                rObjects.Add(items.Shader("DYNGRID"), "DYNGRIDRENDER", gridrenderable);
            }

            if ((ctrlo & 64) != 0)
            {
                gridbitmapvertshader = new DynamicGridCoordVertexShader();
                var frag = new GLPLFragmentShaderTexture2DIndexed(0);

                GLRenderState rl = GLRenderState.Tri(cullface: false);

                GLTexture2DArray gridtexcoords = new GLTexture2DArray();
                items.Add(gridtexcoords, "PLGridBitmapTextures");

                GLShaderPipeline sp = new GLShaderPipeline(gridbitmapvertshader, frag);
                items.Add(sp, "DYNGRIDBitmap");

                rObjects.Add(items.Shader("DYNGRIDBitmap"), "DYNGRIDBitmapRENDER", GLRenderableItem.CreateNullVertex(OpenTK.Graphics.OpenGL4.PrimitiveType.TriangleStrip, rl, drawcount: 4, instancecount: 9));
            }

            GLStorageBlock findresults = items.NewStorageBlock(findblock);

            float sunsize = .5f;

            if ((ctrlo & 128) != 0)
            {
                Random rnd = new Random(52);
                List <HistoryEntry> pos    = new List <HistoryEntry>();
                DateTime            start  = new DateTime(2020, 1, 1);
                Color[]             colors = new Color[] { Color.Red, Color.Green, Color.Blue, Color.White, Color.Black, Color.Purple, Color.Yellow };
                for (int j = 0; j <= 200; j++)
                {
                    Color  jc   = colors[j % colors.Length];
                    int    i    = j * 10;
                    string name = "Kyli Flyuae AA-B h" + j.ToString();
                    if (i < 30000)
                    {
                        pos.Add(new HistoryEntry(start, name, i + rnd.Next(50), rnd.Next(50), i, jc));
                    }
                    else if (i < 60000)
                    {
                        pos.Add(new HistoryEntry(start, name, 60000 - i + rnd.Next(50), rnd.Next(50), i, jc));
                    }
                    else if (i < 90000)
                    {
                        pos.Add(new HistoryEntry(start, name, -(i - 60000) + rnd.Next(50), rnd.Next(50), 120000 - i, jc));
                    }
                    else
                    {
                        pos.Add(new HistoryEntry(start, name, -30000 + (i - 90000) + rnd.Next(50), rnd.Next(50), -i + 120000, jc));
                    }

                    start = start.AddDays(1);
                }

                // tested to 50k stars

                travelpath = new TravelPath(1000);
                travelpath.Create(items, rObjects, pos, sunsize, sunsize, findresults, true);
                travelpath.SetSystem(0);
            }

            if ((ctrlo & 256) != 0)
            {
                galmapobjects = new GalMapObjects();
                galmapobjects.CreateObjects(items, rObjects, edsmmapping, findresults, true);
            }

            if ((ctrlo & 512) != 0)
            {
                //  galaxystars = new GalaxyStars(items, rObjects, sunsize, findresults);
            }

            if ((ctrlo & 1024) != 0)
            {
                rightclickmenu = new GLContextMenu("RightClickMenu",
                                                   new GLMenuItem("RCMInfo", "Information")
                {
                    MouseClick = (s, e) => {
                        var nl = NameLocationDescription(rightclickmenu.Tag);
                        System.Diagnostics.Debug.WriteLine($"Info {nl.Item1} {nl.Item2}");
                        // logical name is important as menu uses it to close down
                        GLMessageBox msg = new GLMessageBox("InfoBoxForm-1", displaycontrol, e.WindowLocation,
                                                            nl.Item3, $"{nl.Item1} @ {nl.Item2.X:#.#},{nl.Item2.Y:#.#},{nl.Item2.Z:#.#}", GLMessageBox.MessageBoxButtons.OK, null,
                                                            Color.FromArgb(220, 60, 60, 70), Color.DarkOrange);
                    }
                },
                                                   new GLMenuItem("RCMZoomIn", "Goto Zoom In")
                {
                    MouseClick = (s1, e1) => {
                        var nl = NameLocationDescription(rightclickmenu.Tag);
                        gl3dcontroller.SlewToPositionZoom(nl.Item2, 100, -1);
                    }
                },
                                                   new GLMenuItem("RCMGoto", "Goto Position")
                {
                    MouseClick = (s1, e1) => {
                        var nl = NameLocationDescription(rightclickmenu.Tag);
                        System.Diagnostics.Debug.WriteLine($"Goto {nl.Item1} {nl.Item2}");
                        gl3dcontroller.SlewToPosition(nl.Item2, -1);
                    }
                },
                                                   new GLMenuItem("RCMLookAt", "Look At")
                {
                    MouseClick = (s1, e1) => {
                        var nl = NameLocationDescription(rightclickmenu.Tag);
                        gl3dcontroller.PanTo(nl.Item2, -1);
                    }
                }
                                                   );
            }

            if ((ctrlo & 2048) != 0)
            {
                bookmarks = new Bookmarks();
                var syslist = new List <SystemClass> {
                    new SystemClass("bk1", 1000, 0, 0), new SystemClass("bk1", 1000, 0, 2000),
                };
                bookmarks.Create(items, rObjects, syslist, 10, findresults, false);
            }
            // Matrix calc holding transform info

            matrixcalc = new GLMatrixCalc();
            matrixcalc.PerspectiveNearZDistance = 1f;
            matrixcalc.PerspectiveFarZDistance  = 120000f / lyscale;
            matrixcalc.InPerspectiveMode        = true;
            matrixcalc.ResizeViewPort(this, glwfc.Size);          // must establish size before starting

            // menu system

            displaycontrol           = new GLControlDisplay(items, glwfc, matrixcalc, true, 0.00001f, 0.00001f); // hook form to the window - its the master
            displaycontrol.Font      = new Font("Arial", 10f);
            displaycontrol.Focusable = true;                                                                     // we want to be able to focus and receive key presses.
            displaycontrol.SetFocus();

            // 3d controller

            gl3dcontroller = new Controller3D();
            gl3dcontroller.PosCamera.ZoomMax     = 600; // gives 5ly
            gl3dcontroller.ZoomDistance          = 3000F / lyscale;
            gl3dcontroller.PosCamera.ZoomMin     = 0.1f;
            gl3dcontroller.PosCamera.ZoomScaling = 1.1f;
            gl3dcontroller.YHoldMovement         = true;
            gl3dcontroller.PaintObjects          = Controller3DDraw;
            gl3dcontroller.KeyboardTravelSpeed   = (ms, eyedist) =>
            {
                double eyedistr = Math.Pow(eyedist, 1.0);
                float  v        = (float)Math.Max(eyedistr / 1200, 0);
                //System.Diagnostics.Debug.WriteLine("Speed " + eyedistr + " "+ v);
                return((float)ms * v);
            };

            // hook gl3dcontroller to display control - its the slave. Do not register mouse UI, we will deal with that.
            gl3dcontroller.Start(matrixcalc, displaycontrol, new Vector3(0, 0, 0), new Vector3(140.75f, 0, 0), 0.5F, false, true);
            //gl3dcontroller.Start(matrixcalc, displaycontrol, new Vector3(0, 0, 0), new Vector3(90F, 0, 0), 0.5F, false, true);

            if (displaycontrol != null)
            {
                displaycontrol.Paint += (o, ts) =>        // subscribing after start means we paint over the scene, letting transparency work
                {
                    // MCUB set up by Controller3DDraw which did the work first
                    galaxymenu.UpdateCoords(gl3dcontroller.MatrixCalc, gl3dcontroller.PosCamera.ZoomFactor);
                    // debug this galaxymenu.DebugStatusText(gl3dcontroller.PosCamera.StringPositionCamera);  gl3dcontroller.PosCamera.SetPositionCamera(gl3dcontroller.PosCamera.StringPositionCamera);
                    displaycontrol.Animate(glwfc.ElapsedTimems);
                    displaycontrol.Render(glwfc.RenderState, ts);
                };
            }

            displaycontrol.MouseClick += MouseClickOnMap;
            displaycontrol.MouseUp    += MouseUpOnMap;
            displaycontrol.MouseDown  += MouseDownOnMap;
            displaycontrol.MouseMove  += MouseMoveOnMap;
            displaycontrol.MouseWheel += MouseWheelOnMap;

            galaxymenu = new MapMenu(this);

            // Autocomplete text box at top for searching

            GLTextBoxAutoComplete tbac = ((GLTextBoxAutoComplete)displaycontrol[MapMenu.EntryTextName]);

            tbac.PerformAutoCompleteInUIThread = (s, a, set) =>
            {
                System.Diagnostics.Debug.Assert(Application.MessageLoop);       // must be in UI thread
                var           glist = edsmmapping.galacticMapObjects.Where(x => s.Length < 3 ? x.name.StartsWith(s, StringComparison.InvariantCultureIgnoreCase) : x.name.Contains(s, StringComparison.InvariantCultureIgnoreCase)).Select(x => x).ToList();
                List <string> list  = glist.Select(x => x.name).ToList();
                list.AddRange(travelpath.CurrentList.Where(x => s.Length < 3 ? x.System.Name.StartsWith(s, StringComparison.InvariantCultureIgnoreCase) : x.System.Name.Contains(s, StringComparison.InvariantCultureIgnoreCase)).Select(x => x.System.Name));
                foreach (var x in list)
                {
                    set.Add(x);
                }
            };

            tbac.SelectedEntry = (a) =>                                   // in UI thread
            {
                System.Diagnostics.Debug.Assert(Application.MessageLoop); // must be in UI thread
                System.Diagnostics.Debug.WriteLine("Selected " + tbac.Text);
                var gmo = edsmmapping.galacticMapObjects.Find(x => x.name.Equals(tbac.Text, StringComparison.InvariantCultureIgnoreCase));
                if (gmo != null)
                {
                    System.Diagnostics.Debug.WriteLine("Move to gmo " + gmo.points[0]);
                    gl3dcontroller.SlewToPosition(new Vector3((float)gmo.points[0].X, (float)gmo.points[0].Y, (float)gmo.points[0].Z), -1);
                }
                else
                {
                    var he = travelpath.CurrentList.Find(x => x.System.Name.Equals(tbac.Text, StringComparison.InvariantCultureIgnoreCase));
                    if (he != null)
                    {
                        System.Diagnostics.Debug.WriteLine("Move to sys " + he.System.Name);
                        gl3dcontroller.SlewToPosition(new Vector3((float)he.System.X, (float)he.System.Y, (float)he.System.Z), -1);
                    }
                    else
                    {
                        tbac.InErrorCondition = true;
                    }
                }
            };

            if (galaxystars != null)
            {
                galaxystars.Start();
            }

            if (false)         // enable for debug buffer
            {
                debugbuffer = new GLStorageBlock(31, true);
                debugbuffer.AllocateBytes(32000, OpenTK.Graphics.OpenGL4.BufferUsageHint.DynamicCopy);       // set size of vec buffer
            }

            if (false)          // enable for debug
            {
                items.Add(new GLColorShaderObjectTranslation(), "COSOT");
                GLRenderState rc = GLRenderState.Tri(cullface: false);
                rc.DepthTest = false;

                Vector3[] markers = new Vector3[] { new Vector3(0, 0, 0), new Vector3(0, -5, 0), new Vector3(0, -5 - 3.125f / 2f, 0) };

                for (int i = 0; i < markers.Length; i++)
                {
                    rObjects.Add(items.Shader("COSOT"), "marker" + i,
                                 GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Triangles, rc,
                                                                      GLCubeObjectFactory.CreateSolidCubeFromTriangles(0.5f),
                                                                      new Color4[] { Color4.Red, Color4.Green, Color4.Blue, Color4.White, Color4.Cyan, Color4.Orange },
                                                                      new GLRenderDataTranslationRotation(markers[i])
                                                                      ));
                }
            }
        }
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            Closed += ShaderTest_Closed;

            gl3dcontroller = new Controller3D();
            gl3dcontroller.MatrixCalc.PerspectiveNearZDistance = 1f;
            gl3dcontroller.MatrixCalc.PerspectiveFarZDistance  = 100000f;
            gl3dcontroller.ZoomDistance  = 5000F;
            gl3dcontroller.YHoldMovement = true;
            gl3dcontroller.PaintObjects  = ControllerDraw;

            gl3dcontroller.KeyboardTravelSpeed = (ms, eyedist) =>
            {
                return((float)ms * 10.0f);
            };

            gl3dcontroller.MatrixCalc.InPerspectiveMode = true;
            gl3dcontroller.Start(glwfc, new Vector3(0, 0, 10000), new Vector3(140.75f, 0, 0), 0.5F);

            items.Add(new GLMatrixCalcUniformBlock(), "MCUB");      // create a matrix uniform block

            int front = -20000, back = front + 90000, left = -45000, right = left + 90000, vsize = 2000;

            boundingbox = new Vector4[]
            {
                new Vector4(left, -vsize, front, 1),
                new Vector4(left, vsize, front, 1),
                new Vector4(right, vsize, front, 1),
                new Vector4(right, -vsize, front, 1),

                new Vector4(left, -vsize, back, 1),
                new Vector4(left, vsize, back, 1),
                new Vector4(right, vsize, back, 1),
                new Vector4(right, -vsize, back, 1),
            };

            Vector4[] displaylines = new Vector4[]
            {
                new Vector4(left, -vsize, front, 1), new Vector4(left, +vsize, front, 1),
                new Vector4(left, +vsize, front, 1), new Vector4(right, +vsize, front, 1),
                new Vector4(right, +vsize, front, 1), new Vector4(right, -vsize, front, 1),
                new Vector4(right, -vsize, front, 1), new Vector4(left, -vsize, front, 1),

                new Vector4(left, -vsize, back, 1), new Vector4(left, +vsize, back, 1),
                new Vector4(left, +vsize, back, 1), new Vector4(right, +vsize, back, 1),
                new Vector4(right, +vsize, back, 1), new Vector4(right, -vsize, back, 1),
                new Vector4(right, -vsize, back, 1), new Vector4(left, -vsize, back, 1),

                new Vector4(left, -vsize, front, 1), new Vector4(left, -vsize, back, 1),
                new Vector4(left, +vsize, front, 1), new Vector4(left, +vsize, back, 1),
                new Vector4(right, -vsize, front, 1), new Vector4(right, -vsize, back, 1),
                new Vector4(right, +vsize, front, 1), new Vector4(right, +vsize, back, 1),
            };

            {
                items.Add(new GLFixedShader(System.Drawing.Color.Yellow), "LINEYELLOW");
                GLRenderState rl = GLRenderState.Lines(1);
                rObjects.Add(items.Shader("LINEYELLOW"), GLRenderableItem.CreateVector4(items, PrimitiveType.Lines, rl, displaylines));
            }

            Bitmap[] numbitmaps    = new Bitmap[116];

            {
                Font fnt = new Font("Arial", 20);
                for (int i = 0; i < numbitmaps.Length; i++)
                {
                    int v = -45000 + 1000 * i;      // range from -45000 to +70000
                    numbitmaps[i] = new Bitmap(100, 100);
                    GLOFC.Utils.BitMapHelpers.DrawTextCentreIntoBitmap(ref numbitmaps[i], v.ToString(), fnt, System.Drawing.Text.TextRenderingHint.ClearTypeGridFit, Color.Red, Color.AliceBlue);
                }

                GLTexture2DArray numtextures = new GLTexture2DArray(numbitmaps, SizedInternalFormat.Rgba8, ownbmp: true);
                items.Add(numtextures, "Nums");

                Matrix4[] numberposx = new Matrix4[(right - left) / 1000 + 1];
                for (int i = 0; i < numberposx.Length; i++)
                {
                    numberposx[i]  = Matrix4.CreateScale(1);
                    numberposx[i] *= Matrix4.CreateRotationX(-25f.Radians());
                    numberposx[i] *= Matrix4.CreateTranslation(new Vector3(left + 1000 * i, 0, front));
                }

                GLShaderPipeline numshaderx = new GLShaderPipeline(new GLPLVertexShaderModelMatrixTexture(), new GLPLFragmentShaderTexture2DIndexed(0));
                items.Add(numshaderx, "IC-X");

                GLRenderState       rq = GLRenderState.Quads(cullface: false);
                GLRenderDataTexture rt = new GLRenderDataTexture(items.Tex("Nums"));

                rObjects.Add(numshaderx, "xnum",
                             GLRenderableItem.CreateVector4Vector2Matrix4(items, PrimitiveType.Quads, rq,
                                                                          GLShapeObjectFactory.CreateQuad(500.0f), GLShapeObjectFactory.TexQuadCW, numberposx,
                                                                          rt, numberposx.Length));

                Matrix4[] numberposz = new Matrix4[(back - front) / 1000 + 1];
                for (int i = 0; i < numberposz.Length; i++)
                {
                    numberposz[i]  = Matrix4.CreateScale(1);
                    numberposz[i] *= Matrix4.CreateRotationX(-25f.Radians());
                    numberposz[i] *= Matrix4.CreateTranslation(new Vector3(right + 1000, 0, front + 1000 * i));
                }

                GLShaderPipeline numshaderz = new GLShaderPipeline(new GLPLVertexShaderModelMatrixTexture(), new GLPLFragmentShaderTexture2DIndexed(25));
                items.Add(numshaderz, "IC-Z");

                rObjects.Add(numshaderz, "ynum",
                             GLRenderableItem.CreateVector4Vector2Matrix4(items, PrimitiveType.Quads, rq,
                                                                          GLShapeObjectFactory.CreateQuad(500.0f), GLShapeObjectFactory.TexQuadCW, numberposz,
                                                                          rt, numberposz.Length));
            }

            items.Add(new GLColorShaderWorld(), "COSW");

            float h = 50;

            if (h != -1)
            {
                GLRenderState rl = GLRenderState.Lines(1);

                int dist = 1000;
                //20?
                Color cr = Color.FromArgb(50, Color.Red);
                rObjects.Add(items.Shader("COSW"),    // horizontal
                             GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Lines, rl,
                                                                  GLShapeObjectFactory.CreateLines(new Vector3(left, h, front), new Vector3(left, h, back), new Vector3(dist, 0, 0), (back - front) / dist + 1),
                                                                  new Color4[] { cr })
                             );

                rObjects.Add(items.Shader("COSW"),
                             GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Lines, rl,
                                                                  GLShapeObjectFactory.CreateLines(new Vector3(left, h, front), new Vector3(right, h, front), new Vector3(0, 0, dist), (right - left) / dist + 1),
                                                                  new Color4[] { cr })
                             );
            }

            {
                items.Add(new GLTexture2D(numbitmaps[45], SizedInternalFormat.Rgba8), "solmarker");
                items.Add(new GLTexturedShaderObjectTranslation(), "TEX");
                GLRenderState rq = GLRenderState.Quads(cullface: false);
                rObjects.Add(items.Shader("TEX"),
                             GLRenderableItem.CreateVector4Vector2(items, PrimitiveType.Quads, rq,
                                                                   GLShapeObjectFactory.CreateQuad(1000.0f, 1000.0f, new Vector3(0, 0, 0)), GLShapeObjectFactory.TexQuadCW,
                                                                   new GLRenderDataTranslationRotationTexture(items.Tex("solmarker"), new Vector3(0, 1000, 0))
                                                                   ));
                rObjects.Add(items.Shader("TEX"),
                             GLRenderableItem.CreateVector4Vector2(items, PrimitiveType.Quads, rq,
                                                                   GLShapeObjectFactory.CreateQuad(1000.0f, 1000.0f, new Vector3(0, 0, 0)), GLShapeObjectFactory.TexQuadCW,
                                                                   new GLRenderDataTranslationRotationTexture(items.Tex("solmarker"), new Vector3(0, -1000, 0))
                                                                   ));
                items.Add(new GLTexture2D(Properties.Resources.dotted, SizedInternalFormat.Rgba8), "sag");
                rObjects.Add(items.Shader("TEX"),
                             GLRenderableItem.CreateVector4Vector2(items, PrimitiveType.Quads, rq,
                                                                   GLShapeObjectFactory.CreateQuad(1000.0f, 1000.0f, new Vector3(0, 0, 0)), GLShapeObjectFactory.TexQuadCW,
                                                                   new GLRenderDataTranslationRotationTexture(items.Tex("sag"), new Vector3(25.2f, 2000, 25899))
                                                                   ));
                rObjects.Add(items.Shader("TEX"),
                             GLRenderableItem.CreateVector4Vector2(items, PrimitiveType.Quads, rq,
                                                                   GLShapeObjectFactory.CreateQuad(1000.0f, 1000.0f, new Vector3(0, 0, 0)), GLShapeObjectFactory.TexQuadCW,
                                                                   new GLRenderDataTranslationRotationTexture(items.Tex("sag"), new Vector3(25.2f, -2000, 25899))
                                                                   ));
                items.Add(new GLTexture2D(Properties.Resources.dotted2, SizedInternalFormat.Rgba8), "bp");
                rObjects.Add(items.Shader("TEX"),
                             GLRenderableItem.CreateVector4Vector2(items, PrimitiveType.Quads, rq,
                                                                   GLShapeObjectFactory.CreateQuad(1000.0f, 1000.0f, new Vector3(0, 0, 0)), GLShapeObjectFactory.TexQuadCW,
                                                                   new GLRenderDataTranslationRotationTexture(items.Tex("bp"), new Vector3(-1111f, 0, 65269))
                                                                   ));
            }


            if (true) // galaxy
            {
                volumetricblock = new GLVolumetricUniformBlock();
                items.Add(volumetricblock, "VB");

                int         sc      = 1;
                GLTexture3D noise3d = new GLTexture3D(1024 * sc, 64 * sc, 1024 * sc, OpenTK.Graphics.OpenGL4.SizedInternalFormat.R32f);         // red channel only
                items.Add(noise3d, "Noise");
                ComputeShaderNoise3D csn = new ComputeShaderNoise3D(noise3d.Width, noise3d.Height, noise3d.Depth, 128 * sc, 16 * sc, 128 * sc); // must be a multiple of localgroupsize in csn
                csn.StartAction += (A, m) => { noise3d.BindImage(3); };
                csn.Run();                                                                                                                      // compute noise

                GLTexture1D gaussiantex = new GLTexture1D(1024, OpenTK.Graphics.OpenGL4.SizedInternalFormat.R32f);                              // red channel only
                items.Add(gaussiantex, "Gaussian");

                // set centre=width, higher widths means more curve, higher std dev compensate.
                // fill the gaussiantex with data
                ComputeShaderGaussian gsn = new ComputeShaderGaussian(gaussiantex.Width, 2.0f, 2.0f, 1.4f, 4);
                gsn.StartAction += (A, m) => { gaussiantex.BindImage(4); };
                gsn.Run();      // compute noise

                GL.MemoryBarrier(MemoryBarrierFlags.AllBarrierBits);

                //float[] gdata = gaussiantex.GetTextureImageAsFloats(OpenTK.Graphics.OpenGL4.PixelFormat.Red); // read back check
                //for( int i = 0; i < gdata.Length; i++  )
                //{
                //    double v = ((float)i / gdata.Length-0.5)*2*2;
                //    double r = ObjectExtensionsNumbersBool.GaussianDist(v, 2, 1.4);
                // //   System.Diagnostics.Debug.WriteLine(i + ":" + gdata[i] + ": " +  r);
                //}

                // load one upside down and horz flipped, because the volumetric co-ords are 0,0,0 bottom left, 1,1,1 top right
                GLTexture2D galtex = new GLTexture2D(Properties.Resources.Galaxy_L180, SizedInternalFormat.Rgba8);
                items.Add(galtex, "gal");
                GalaxyShader gs = new GalaxyShader();
                items.Add(gs, "Galaxy");
                // bind the galaxy texture, the 3dnoise, and the gaussian 1-d texture for the shader
                gs.StartAction = (a, m) => { galtex.Bind(1); noise3d.Bind(3); gaussiantex.Bind(4); };      // shader requires these, so bind using shader

                GLRenderState rt = GLRenderState.Tri();
                galaxy = GLRenderableItem.CreateNullVertex(PrimitiveType.Points, rt);   // no vertexes, all data from bound volumetric uniform, no instances as yet
                rObjects.Add(items.Shader("Galaxy"), galaxy);
            }

            if (true) // star points
            {
                int    gran = 8;
                Bitmap img  = Properties.Resources.Galaxy_L180;
                Bitmap heat = img.Function(img.Width / gran, img.Height / gran, mode: GLOFC.Utils.BitMapHelpers.BitmapFunction.HeatMap);
                heat.Save(@"c:\code\heatmap.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);

                if (false)       // heat map checkout debug
                {
                    List <Vector4> points = new List <Vector4>();

                    int xcw = (right - left) / heat.Width;
                    int zch = (back - front) / heat.Height;

                    for (int x = 0; x < heat.Width; x++)
                    {
                        for (int z = 0; z < heat.Height; z++)
                        {
                            int   gx = left + x * xcw + xcw / 2;
                            int   gz = front + z * zch + zch / 2;
                            Color px = heat.GetPixel(x, z);
                            //System.Diagnostics.Debug.WriteLine(x + "," + z + " = " + gx + "," + gz + " : " + px.R);
                            points.Add(new Vector4(gx, 2000, gz, px.R));
                        }
                    }

                    items.Add(new GLHeatMapIntensity(), "ShP");
                    GLRenderState rp = GLRenderState.Points();
                    rp.DepthTest = false;
                    rObjects.Add(items.Shader("ShP"), GLRenderableItem.CreateVector4(items, PrimitiveType.Points, rp, points.ToArray()));
                }

                if (false)      // v1 via array
                {
                    List <Vector4> points = new List <Vector4>();
                    Random         rnd    = new Random(23);

                    int xcw = (right - left) / heat.Width;
                    int zch = (back - front) / heat.Height;

                    for (int x = 0; x < heat.Width; x++)
                    {
                        for (int z = 0; z < heat.Height; z++)
                        {
                            int i  = heat.GetPixel(x, z).R;
                            int ii = i * i * i;
                            if (ii > 32 * 32 * 32)
                            {
                                int gx = left + x * xcw;
                                int gz = front + z * zch;

                                float  dx = (float)Math.Abs(gx) / 45000;
                                float  dz = (float)Math.Abs(25889 - gz) / 45000;
                                double d  = Math.Sqrt(dx * dx + dz * dz); // 0 - 0.1412
                                d = 1 - d;                                // 1 = centre, 0 = unit circle
                                d = d * 2 - 1;                            // -1 to +1
                                double dist = ObjectExtensionsNumbersBool.GaussianDist(d, 1, 1.4);

                                int c = Math.Min(Math.Max(ii / 100000, 0), 20);

                                dist *= 2000;

                                var rs = GLPointsFactory.RandomStars4(c, gx, gx + xcw, gz, gz + zch, (int)dist, (int)-dist, rnd, w: i);

                                if (z == heat.Height / 2)
                                {
                                    System.Diagnostics.Debug.WriteLine(gx + "," + gz + "; " + dx + "," + dz + " = " + i + " " + c + " " + d + "=h " + dist);
                                }
                                //var rs = GLPointsFactory.RandomStars4(500, gx, gx + xcw, gz, gz + zch, (int)dist, (int)-dist, rnd, w:i);
                                points.AddRange(rs);
                            }
                        }
                    }

                    items.Add(new GalaxyStarDots(), "SD");
                    GLRenderState rp = GLRenderState.Points(1);
                    rp.DepthTest = false;

                    rObjects.Add(items.Shader("SD"), GLRenderableItem.CreateVector4(items, PrimitiveType.Points, rp, points.ToArray()));
                }

                if (true)  //v2 direct to buffer
                {
                    Random rnd = new Random(23);

                    GLBuffer buf = new GLBuffer(16 * 500000); // since RND is fixed, should get the same number every time.
                    buf.StartWrite(0);                        // get a ptr to the whole schebang

                    int xcw = (right - left) / heat.Width;
                    int zch = (back - front) / heat.Height;

                    int points = 0;

                    for (int x = 0; x < heat.Width; x++)
                    {
                        for (int z = 0; z < heat.Height; z++)
                        {
                            int i  = heat.GetPixel(x, z).R;
                            int ii = i * i * i;
                            if (ii > 32 * 32 * 32)
                            {
                                int gx = left + x * xcw;
                                int gz = front + z * zch;

                                float  dx = (float)Math.Abs(gx) / 45000;
                                float  dz = (float)Math.Abs(25889 - gz) / 45000;
                                double d  = Math.Sqrt(dx * dx + dz * dz); // 0 - 0.1412
                                d = 1 - d;                                // 1 = centre, 0 = unit circle
                                d = d * 2 - 1;                            // -1 to +1
                                double dist = ObjectExtensionsNumbersBool.GaussianDist(d, 1, 1.4);

                                int c = Math.Min(Math.Max(ii / 140000, 0), 40);

                                dist *= 2000;

                                GLPointsFactory.RandomStars4(buf, c, gx, gx + xcw, gz, gz + zch, (int)dist, (int)-dist, rnd, w: i);
                                points += c;
                                System.Diagnostics.Debug.Assert(points < buf.Length / 16);
                            }
                        }
                    }

                    buf.StopReadWrite();

                    items.Add(new GalaxyStarDots(), "SD");
                    GLRenderState rp = GLRenderState.Points(1);
                    rp.DepthTest = false;
                    rObjects.Add(items.Shader("SD"),
                                 GLRenderableItem.CreateVector4(items, PrimitiveType.Points, rp, buf, points));
                    System.Diagnostics.Debug.WriteLine("Stars " + points);
                }
            }

            if (true)  // point sprite
            {
                items.Add(new GLTexture2D(Properties.Resources.star_grey64, SizedInternalFormat.Rgba8), "lensflare");
                items.Add(new GLPointSpriteShader(items.Tex("lensflare")), "PS1");
                int dist = 20000;
                var p    = GLPointsFactory.RandomStars4(100, -dist, dist, 25899 - dist, 25899 + dist, 2000, -2000);

                GLRenderState rps = GLRenderState.PointSprites();
                rps.DepthTest = false;

                rObjects.Add(items.Shader("PS1"),
                             GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Points, rps, p, new Color4[] { Color.White }));
            }
        }
Exemplo n.º 4
0
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            Closed += ShaderTest_Closed;

            //GLStatics.EnableDebug(DebugProc);

            gl3dcontroller = new Controller3D();
            gl3dcontroller.PaintObjects = ControllerDraw;
            gl3dcontroller.MatrixCalc.PerspectiveNearZDistance = 1f;
            gl3dcontroller.MatrixCalc.PerspectiveFarZDistance  = 500000f;
            gl3dcontroller.ZoomDistance  = 5000F;
            gl3dcontroller.YHoldMovement = true;

            gl3dcontroller.KeyboardTravelSpeed = (ms, eyedist) =>
            {
                return((float)ms * 10.0f);
            };

            gl3dcontroller.MatrixCalc.InPerspectiveMode = true;
            gl3dcontroller.Start(glwfc, new Vector3(0, 0, -35000), new Vector3(135f, 0, 0), 0.31622F);


            items.Add(new GLColorShaderWorld(), "COSW");
            GLRenderState rl1 = GLRenderState.Lines(1);

            float h = -1;

            if (h != -1)
            {
                Color cr = Color.FromArgb(60, Color.Gray);
                rObjects.Add(items.Shader("COS-1L"),    // horizontal
                             GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Lines, rl1,
                                                                  GLShapeObjectFactory.CreateLines(new Vector3(-35000, h, -35000), new Vector3(-35000, h, 35000), new Vector3(1000, 0, 0), 70),
                                                                  new Color4[] { cr })
                             );

                rObjects.Add(items.Shader("COS-1L"),
                             GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Lines, rl1,
                                                                  GLShapeObjectFactory.CreateLines(new Vector3(-35000, h, -35000), new Vector3(35000, h, -35000), new Vector3(0, 0, 1000), 70),
                                                                  new Color4[] { cr })
                             );
            }

            int hsize = 35000, vsize = 2000, zsize = 35000;

            {
                int       left = -hsize, right = hsize, bottom = -vsize, top = +vsize, front = -zsize, back = zsize;
                Vector4[] lines2 = new Vector4[]
                {
                    new Vector4(left, bottom, front, 1), new Vector4(left, top, front, 1),
                    new Vector4(left, top, front, 1), new Vector4(right, top, front, 1),
                    new Vector4(right, top, front, 1), new Vector4(right, bottom, front, 1),
                    new Vector4(right, bottom, front, 1), new Vector4(left, bottom, front, 1),

                    new Vector4(left, bottom, back, 1), new Vector4(left, top, back, 1),
                    new Vector4(left, top, back, 1), new Vector4(right, top, back, 1),
                    new Vector4(right, top, back, 1), new Vector4(right, bottom, back, 1),
                    new Vector4(right, bottom, back, 1), new Vector4(left, bottom, back, 1),

                    new Vector4(left, bottom, front, 1), new Vector4(left, bottom, back, 1),
                    new Vector4(left, top, front, 1), new Vector4(left, top, back, 1),
                    new Vector4(right, bottom, front, 1), new Vector4(right, bottom, back, 1),
                    new Vector4(right, top, front, 1), new Vector4(right, top, back, 1),
                };

                items.Add(new GLFixedShader(System.Drawing.Color.Yellow), "LINEYELLOW");
                rObjects.Add(items.Shader("LINEYELLOW"),
                             GLRenderableItem.CreateVector4(items, PrimitiveType.Lines, rl1, lines2));
            }

            // bounding box

            boundingbox = new Vector4[]
            {
                new Vector4(-hsize, -vsize, -zsize, 1),
                new Vector4(-hsize, vsize, -zsize, 1),
                new Vector4(hsize, vsize, -zsize, 1),
                new Vector4(hsize, -vsize, -zsize, 1),

                new Vector4(-hsize, -vsize, zsize, 1),
                new Vector4(-hsize, vsize, zsize, 1),
                new Vector4(hsize, vsize, zsize, 1),
                new Vector4(hsize, -vsize, zsize, 1),
            };

            items.Add(new GLMatrixCalcUniformBlock(), "MCUB");      // create a matrix uniform block

            dataoutbuffer = items.NewStorageBlock(5);
            dataoutbuffer.AllocateBytes(sizeof(float) * 4 * 32, OpenTK.Graphics.OpenGL4.BufferUsageHint.DynamicRead);    // 32 vec4 back

            atomicbuffer = items.NewAtomicBlock(6);
            atomicbuffer.AllocateBytes(sizeof(float) * 32, OpenTK.Graphics.OpenGL4.BufferUsageHint.DynamicCopy);

            dataoutbuffer = items.NewStorageBlock(5);
            dataoutbuffer.AllocateBytes(sizeof(float) * 4 * 256, OpenTK.Graphics.OpenGL4.BufferUsageHint.DynamicRead);    // 32 vec4 back

            volumetricblock = new GLVolumetricUniformBlock();
            items.Add(volumetricblock, "VB");

            {
                Bitmap[]  numbers    = new Bitmap[70];
                Matrix4[] numberpos  = new Matrix4[numbers.Length];
                Matrix4[] numberpos2 = new Matrix4[numbers.Length];

                Font fnt = new Font("Arial", 20);

                for (int i = 0; i < numbers.Length; i++)
                {
                    int v = -35000 + i * 1000;
                    numbers[i] = new Bitmap(100, 100);
                    GLOFC.Utils.BitMapHelpers.DrawTextCentreIntoBitmap(ref numbers[i], v.ToString(), fnt, System.Drawing.Text.TextRenderingHint.ClearTypeGridFit, Color.Red, Color.AliceBlue);

                    numberpos[i]   = Matrix4.CreateScale(1);
                    numberpos[i]  *= Matrix4.CreateRotationX(-25f.Radians());
                    numberpos[i]  *= Matrix4.CreateTranslation(new Vector3(35500, 0, v));
                    numberpos2[i]  = Matrix4.CreateScale(1);
                    numberpos2[i] *= Matrix4.CreateRotationX(-25f.Radians());
                    numberpos2[i] *= Matrix4.CreateTranslation(new Vector3(v, 0, -35500));
                }

                GLTexture2DArray array = new GLTexture2DArray(numbers, SizedInternalFormat.Rgba8, ownbmp: true);
                items.Add(array, "Nums");
                items.Add(new GLShaderPipeline(new GLPLVertexShaderModelMatrixTexture(), new GLPLFragmentShaderTexture2DIndexed(0)), "IC-2");

                GLRenderState       rq = GLRenderState.Quads(cullface: false);
                GLRenderDataTexture rt = new GLRenderDataTexture(items.Tex("Nums"));

                rObjects.Add(items.Shader("IC-2"), "1-b",
                             GLRenderableItem.CreateVector4Vector2Matrix4(items, PrimitiveType.Quads, rq,
                                                                          GLShapeObjectFactory.CreateQuad(500.0f), GLShapeObjectFactory.TexQuadCW, numberpos,
                                                                          rt, numberpos.Length));

                rObjects.Add(items.Shader("IC-2"), "1-b2",
                             GLRenderableItem.CreateVector4Vector2Matrix4(items, PrimitiveType.Quads, rq,
                                                                          GLShapeObjectFactory.CreateQuad(500.0f), GLShapeObjectFactory.TexQuadCW, numberpos2,
                                                                          rt, numberpos.Length));
            }

            GLTexture3D noise3d = new GLTexture3D(1024, 64, 1024, OpenTK.Graphics.OpenGL4.SizedInternalFormat.R32f); // red channel only

            //{     // shows program fill
            //    for (int ly = 0; ly < noise3d.Depth; ly++)
            //    {
            //        float[] fd = new float[noise3d.Width * noise3d.Height];
            //        float[] fdi = new float[noise3d.Width * noise3d.Height];
            //        for (int x = 0; x < noise3d.Width; x++)
            //        {
            //            for (int y = 0; y < noise3d.Height; y++)
            //            {
            //                int p = (y * noise3d.Width + x) * 1;

            //                float xv = (float)x / (float)noise3d.Width;
            //                float yv = (float)y / (float)noise3d.Height;

            //                var c = ((Math.Sin(2 * Math.PI * xv) / 2) + 0.5);
            //                c += ((Math.Cos(2 * Math.PI * yv) / 2) + 0.5);

            //                c /= 2;

            //                fd[p + 0] = (float)(c);
            //                fdi[p + 0] = 1.0f-(float)(c);
            //            }
            //        }

            //        noise3d.StoreZPlane(ly, 0, 0, noise3d.Width, noise3d.Height, fd, OpenTK.Graphics.OpenGL4.PixelFormat.Red);        // only a single float per pixel, stored in RED

            //    }
            //}

            ShaderNoiseDisplay ns = new ShaderNoiseDisplay();

            ns.StartAction += (a, m) => { noise3d.Bind(3); };
            items.Add(ns, "NS");
            GLRenderState rv = GLRenderState.Tri();

            noisebox = GLRenderableItem.CreateNullVertex(OpenTK.Graphics.OpenGL4.PrimitiveType.Points, rv);   // no vertexes, all data from bound volumetric uniform, no instances as yet

            rObjects.Add(items.Shader("NS"), noisebox);

            // make a compute shader noise and run it, to fill up noise3d buffer

            ComputeShaderNoise csn = new ComputeShaderNoise(noise3d.Width, noise3d.Height, noise3d.Depth, 32, 4, 32);       // must be a multiple of localgroupsize in csn

            csn.StartAction += (A, m) => { noise3d.BindImage(3); };
            items.Add(csn, "CE1");
            GLComputeShaderList p = new GLComputeShaderList();      // demonstrate a render list holding a compute shader.

            p.Add(csn);
            p.Run();        // run the shader to compute into the noise3d block the noise.
        }
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            Closed += ShaderTest_Closed;

            gl3dcontroller = new Controller3D();
            gl3dcontroller.PaintObjects = ControllerDraw;
            gl3dcontroller.MatrixCalc.PerspectiveNearZDistance = 1f;
            gl3dcontroller.MatrixCalc.PerspectiveFarZDistance  = 500000f;
            gl3dcontroller.ZoomDistance  = 5000F;
            gl3dcontroller.YHoldMovement = true;

            gl3dcontroller.KeyboardTravelSpeed = (ms, eyedist) =>
            {
                return((float)ms * 10.0f);
            };

            gl3dcontroller.MatrixCalc.InPerspectiveMode = true;
            gl3dcontroller.Start(glwfc, new Vector3(0, 0, -35000), new Vector3(126.75f, 0, 0), 0.31622F);

            int front = -20000, back = front + 90000, left = -45000, right = left + 90000, vsize = 2000;

            items.Add(new GLColorShaderWorld(), "COSW");
            GLRenderState rl1 = GLRenderState.Lines(1);

            float h = -1;

            if (h != -1)
            {
                int   dist = 1000;
                Color cr   = Color.FromArgb(20, Color.Red);
                rObjects.Add(items.Shader("COS-1L"),    // horizontal
                             GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Lines, rl1,
                                                                  GLShapeObjectFactory.CreateLines(new Vector3(left, h, front), new Vector3(left, h, back), new Vector3(dist, 0, 0), (back - front) / dist + 1),
                                                                  new Color4[] { cr })
                             );

                rObjects.Add(items.Shader("COS-1L"),
                             GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Lines, rl1,
                                                                  GLShapeObjectFactory.CreateLines(new Vector3(left, h, front), new Vector3(right, h, front), new Vector3(0, 0, dist), (right - left) / dist + 1),
                                                                  new Color4[] { cr })
                             );
            }

            {
                Vector4[] displaylines = new Vector4[]
                {
                    new Vector4(left, -vsize, front, 1), new Vector4(left, +vsize, front, 1),
                    new Vector4(left, +vsize, front, 1), new Vector4(right, +vsize, front, 1),
                    new Vector4(right, +vsize, front, 1), new Vector4(right, -vsize, front, 1),
                    new Vector4(right, -vsize, front, 1), new Vector4(left, -vsize, front, 1),

                    new Vector4(left, -vsize, back, 1), new Vector4(left, +vsize, back, 1),
                    new Vector4(left, +vsize, back, 1), new Vector4(right, +vsize, back, 1),
                    new Vector4(right, +vsize, back, 1), new Vector4(right, -vsize, back, 1),
                    new Vector4(right, -vsize, back, 1), new Vector4(left, -vsize, back, 1),

                    new Vector4(left, -vsize, front, 1), new Vector4(left, -vsize, back, 1),
                    new Vector4(left, +vsize, front, 1), new Vector4(left, +vsize, back, 1),
                    new Vector4(right, -vsize, front, 1), new Vector4(right, -vsize, back, 1),
                    new Vector4(right, +vsize, front, 1), new Vector4(right, +vsize, back, 1),
                };

                items.Add(new GLFixedColorShaderWorld(System.Drawing.Color.Yellow), "LINEYELLOW");
                rObjects.Add(items.Shader("LINEYELLOW"),
                             GLRenderableItem.CreateVector4(items, PrimitiveType.Lines, rl1, displaylines));
            }


            Bitmap[] numbitmaps = new Bitmap[116];

            {
                Font fnt = new Font("Arial", 20);
                for (int i = 0; i < numbitmaps.Length; i++)
                {
                    int v = -45000 + 1000 * i;      // range from -45000 to +70000
                    numbitmaps[i] = new Bitmap(100, 100);
                    GLOFC.Utils.BitMapHelpers.DrawTextCentreIntoBitmap(ref numbitmaps[i], v.ToString(), fnt, System.Drawing.Text.TextRenderingHint.ClearTypeGridFit, Color.Red, Color.AliceBlue);
                }

                GLTexture2DArray numtextures = new GLTexture2DArray(numbitmaps, SizedInternalFormat.Rgba8, ownbmp: true);
                items.Add(numtextures, "Nums");

                Matrix4[] numberposx = new Matrix4[(right - left) / 1000 + 1];
                for (int i = 0; i < numberposx.Length; i++)
                {
                    numberposx[i]  = Matrix4.CreateScale(1);
                    numberposx[i] *= Matrix4.CreateRotationX(-25f.Radians());
                    numberposx[i] *= Matrix4.CreateTranslation(new Vector3(left + 1000 * i, 0, front));
                }

                GLShaderPipeline numshaderx = new GLShaderPipeline(new GLPLVertexShaderModelMatrixTexture(), new GLPLFragmentShaderTexture2DIndexed(0));
                items.Add(numshaderx, "IC-X");

                GLRenderState       rq = GLRenderState.Quads(cullface: false);
                GLRenderDataTexture rt = new GLRenderDataTexture(items.Tex("Nums"));

                rObjects.Add(numshaderx, "xnum",
                             GLRenderableItem.CreateVector4Vector2Matrix4(items, PrimitiveType.Quads, rq,
                                                                          GLShapeObjectFactory.CreateQuad(500.0f), GLShapeObjectFactory.TexQuadCW, numberposx,
                                                                          rt, numberposx.Length));

                Matrix4[] numberposz = new Matrix4[(back - front) / 1000 + 1];
                for (int i = 0; i < numberposz.Length; i++)
                {
                    numberposz[i]  = Matrix4.CreateScale(1);
                    numberposz[i] *= Matrix4.CreateRotationX(-25f.Radians());
                    numberposz[i] *= Matrix4.CreateTranslation(new Vector3(right + 1000, 0, front + 1000 * i));
                }

                GLShaderPipeline numshaderz = new GLShaderPipeline(new GLPLVertexShaderModelMatrixTexture(), new GLPLFragmentShaderTexture2DIndexed(25));
                items.Add(numshaderz, "IC-Z");

                rObjects.Add(numshaderz, "ynum",
                             GLRenderableItem.CreateVector4Vector2Matrix4(items, PrimitiveType.Quads, rq,
                                                                          GLShapeObjectFactory.CreateQuad(500.0f), GLShapeObjectFactory.TexQuadCW, numberposz,
                                                                          rt, numberposz.Length));
            }

            {
                items.Add(new GLTexture2D(numbitmaps[45], SizedInternalFormat.Rgba8), "solmarker");
                items.Add(new GLTexturedShaderObjectTranslation(), "TEX");

                GLRenderState rq = GLRenderState.Quads(cullface: false);

                rObjects.Add(items.Shader("TEX"),
                             GLRenderableItem.CreateVector4Vector2(items, PrimitiveType.Quads, rq,
                                                                   GLShapeObjectFactory.CreateQuad(1000.0f, 1000.0f, new Vector3(0, 0, 0)), GLShapeObjectFactory.TexQuadCW,
                                                                   new GLRenderDataTranslationRotationTexture(items.Tex("solmarker"), new Vector3(0, 1000, 0))
                                                                   ));
                rObjects.Add(items.Shader("TEX"),
                             GLRenderableItem.CreateVector4Vector2(items, PrimitiveType.Quads, rq,
                                                                   GLShapeObjectFactory.CreateQuad(1000.0f, 1000.0f, new Vector3(0, 0, 0)), GLShapeObjectFactory.TexQuadCW,
                                                                   new GLRenderDataTranslationRotationTexture(items.Tex("solmarker"), new Vector3(0, -1000, 0))
                                                                   ));
                items.Add(new GLTexture2D(Properties.Resources.dotted, SizedInternalFormat.Rgba8), "sag");
                rObjects.Add(items.Shader("TEX"),
                             GLRenderableItem.CreateVector4Vector2(items, PrimitiveType.Quads, rq,
                                                                   GLShapeObjectFactory.CreateQuad(1000.0f, 1000.0f, new Vector3(0, 0, 0)), GLShapeObjectFactory.TexQuadCW,
                                                                   new GLRenderDataTranslationRotationTexture(items.Tex("sag"), new Vector3(25.2f, 2000, 25899))
                                                                   ));
                rObjects.Add(items.Shader("TEX"),
                             GLRenderableItem.CreateVector4Vector2(items, PrimitiveType.Quads, rq,
                                                                   GLShapeObjectFactory.CreateQuad(1000.0f, 1000.0f, new Vector3(0, 0, 0)), GLShapeObjectFactory.TexQuadCW,
                                                                   new GLRenderDataTranslationRotationTexture(items.Tex("sag"), new Vector3(25.2f, -2000, 25899))
                                                                   ));
                items.Add(new GLTexture2D(Properties.Resources.dotted2, SizedInternalFormat.Rgba8), "bp");
                rObjects.Add(items.Shader("TEX"),
                             GLRenderableItem.CreateVector4Vector2(items, PrimitiveType.Quads, rq,
                                                                   GLShapeObjectFactory.CreateQuad(1000.0f, 1000.0f, new Vector3(0, 0, 0)), GLShapeObjectFactory.TexQuadCW,
                                                                   new GLRenderDataTranslationRotationTexture(items.Tex("bp"), new Vector3(-1111f, 0, 65269))
                                                                   ));
            }

            boundingbox = new Vector4[]
            {
                new Vector4(left, -vsize, front, 1),
                new Vector4(left, vsize, front, 1),
                new Vector4(right, vsize, front, 1),
                new Vector4(right, -vsize, front, 1),

                new Vector4(left, -vsize, back, 1),
                new Vector4(left, vsize, back, 1),
                new Vector4(right, vsize, back, 1),
                new Vector4(right, -vsize, back, 1),
            };

            if (true)
            {
                volumetricblock = new GLVolumetricUniformBlock();
                items.Add(volumetricblock, "VB");

                int         sc      = 1;
                GLTexture3D noise3d = new GLTexture3D(1024 * sc, 64 * sc, 1024 * sc, OpenTK.Graphics.OpenGL4.SizedInternalFormat.R32f);         // red channel only
                items.Add(noise3d, "Noise");
                ComputeShaderNoise3D csn = new ComputeShaderNoise3D(noise3d.Width, noise3d.Height, noise3d.Depth, 128 * sc, 16 * sc, 128 * sc); // must be a multiple of localgroupsize in csn
                csn.StartAction += (A, m) => { noise3d.BindImage(3); };
                csn.Run();                                                                                                                      // compute noise

                GLTexture1D gaussiantex = new GLTexture1D(1024, OpenTK.Graphics.OpenGL4.SizedInternalFormat.R32f);                              // red channel only
                items.Add(gaussiantex, "Gaussian");

                // set centre=width, higher widths means more curve, higher std dev compensate

                ComputeShaderGaussian gsn = new ComputeShaderGaussian(gaussiantex.Width, 2.0f, 2.0f, 1.4f, 4);
                gsn.StartAction += (A, m) => { gaussiantex.BindImage(4); };
                gsn.Run();      // compute noise

                GL.MemoryBarrier(MemoryBarrierFlags.AllBarrierBits);

                float[] gdata = gaussiantex.GetTextureImageAs <float>(OpenTK.Graphics.OpenGL4.PixelFormat.Red); // read back check

                // load one upside down and horz flipped, because the volumetric co-ords are 0,0,0 bottom left, 1,1,1 top right
                GLTexture2D galtex = new GLTexture2D(Properties.Resources.Galaxy_L180, SizedInternalFormat.Rgba8);
                items.Add(galtex, "gal");
                GalaxyShader gs = new GalaxyShader();
                items.Add(gs, "Galaxy");
                gs.StartAction += (a, m) => { galtex.Bind(1); noise3d.Bind(3); gaussiantex.Bind(4); };

                GLRenderState rv = GLRenderState.Tri();
                galaxy = GLRenderableItem.CreateNullVertex(PrimitiveType.Points, rv);   // no vertexes, all data from bound volumetric uniform, no instances as yet
                rObjects.Add(items.Shader("Galaxy"), galaxy);
            }

            items.Add(new GLMatrixCalcUniformBlock(), "MCUB");      // create a matrix uniform block
        }