private void IntCreatePath(GLItemsList items, GLRenderProgramSortedList rObjects, GLStorageBlock bufferfindresults)
        {
            HistoryEntry lastone = lastpos != -1 && lastpos < currentfilteredlist.Count ? currentfilteredlist[lastpos] : null;  // see if lastpos is there, and store it

            if (TravelPathEndDateEnable || TravelPathStartDateEnable)
            {
                currentfilteredlist = unfilteredlist.Where(x => (!TravelPathStartDateEnable || x.EventTimeUTC >= TravelPathStartDate) && (!TravelPathEndDateEnable || x.EventTimeUTC <= TravelPathEndDate)).ToList();
                if (currentfilteredlist.Count > MaxStars)
                {
                    currentfilteredlist = currentfilteredlist.Skip(currentfilteredlist.Count - MaxStars).ToList();
                }
            }
            else
            {
                if (unfilteredlist.Count > MaxStars)
                {
                    currentfilteredlist = unfilteredlist.Skip(currentfilteredlist.Count - MaxStars).ToList();
                }
                else
                {
                    currentfilteredlist = unfilteredlist;
                }
            }

            // do date filter on currentfilteredlist

            lastpos = lastone == null ? -1 : currentfilteredlist.IndexOf(lastone);        // may be -1, may have been removed

            var   positionsv4 = currentfilteredlist.Select(x => new Vector4((float)x.System.X, (float)x.System.Y, (float)x.System.Z, 0)).ToArray();
            var   colours     = currentfilteredlist.Select(x => x.JumpColor).ToArray();
            float seglen      = tapesize * 10;

            // a tape is a set of points (item1) and indexes to select them (item2), so we need an element index in the renderer to use.
            var tape = GLTapeObjectFactory.CreateTape(positionsv4, colours, tapesize, seglen, 0F.Radians(), margin: sunsize * 1.2f);

            if (ritape == null) // first time..
            {
                // first the tape

                var tapetex = new GLTexture2D(Properties.Resources.chevron, internalformat: OpenTK.Graphics.OpenGL4.SizedInternalFormat.Rgba8);        // tape image
                items.Add(tapetex);
                tapetex.SetSamplerMode(OpenTK.Graphics.OpenGL4.TextureWrapMode.Repeat, OpenTK.Graphics.OpenGL4.TextureWrapMode.Repeat);

                tapefrag = new GLPLFragmentShaderTextureTriStripColorReplace(1, Color.FromArgb(255, 206, 0, 0));
                var vert = new GLPLVertexShaderWorldTextureTriStrip();
                tapeshader = new GLShaderPipeline(vert, tapefrag);
                items.Add(tapeshader);

                GLRenderState rts = GLRenderState.Tri(tape.Item3, cullface: false); // set up a Tri strip, primitive restart value set from tape, no culling
                rts.DepthTest = depthtest;                                          // no depth test so always appears

                // now the renderer, set up with the render control, tape as the points, and bind a RenderDataTexture so the texture gets binded each time
                ritape         = GLRenderableItem.CreateVector4(items, OpenTK.Graphics.OpenGL4.PrimitiveType.TriangleStrip, rts, tape.Item1.ToArray(), new GLRenderDataTexture(tapetex));
                tapepointbuf   = items.LastBuffer();                                            // keep buffer for refill
                ritape.Visible = tape.Item1.Count > 0;                                          // no items, set not visible, so it won't except over the BIND with nothing in the element buffer

                ritape.CreateElementIndex(items.NewBuffer(), tape.Item2.ToArray(), tape.Item3); // finally, we are using index to select vertexes, so create an index

                rObjects.Add(tapeshader, "travelpath-tape", ritape);                            // add render to object list

                // now the stars

                starposbuf = items.NewBuffer();         // where we hold the vertexes for the suns, used by renderer and by finder

                starposbuf.AllocateFill(positionsv4);
                //Vector4[] vectors = starposbuf.ReadVector4s(0, starposbuf.Length / 16);

                sunvertex = new GLPLVertexShaderModelCoordWorldAutoscale(new Color[] { Color.Yellow, Color.FromArgb(255, 230, 230, 1) },
                                                                         autoscale: 30, autoscalemin: 1f, autoscalemax: 2f, useeyedistance: false); // below scale, 1f, above scale, scale up to x times (eyedist/scale)
                sunshader = new GLShaderPipeline(sunvertex, new GLPLStarSurfaceFragmentShader());
                items.Add(sunshader);

                var shape = GLSphereObjectFactory.CreateSphereFromTriangles(2, sunsize);

                GLRenderState rt = GLRenderState.Tri();     // render is triangles, with no depth test so we always appear
                rt.DepthTest  = depthtest;
                rt.DepthClamp = true;
                renderersun   = GLRenderableItem.CreateVector4Vector4(items, OpenTK.Graphics.OpenGL4.PrimitiveType.Triangles, rt, shape, starposbuf, 0, null, currentfilteredlist.Count, 1);
                rObjects.Add(sunshader, "travelpath-suns", renderersun);

                // find compute

                var geofind = new GLPLGeoShaderFindTriangles(bufferfindresults, 16);
                findshader = items.NewShaderPipeline(null, sunvertex, null, null, geofind, null, null, null);
                rifind     = GLRenderableItem.CreateVector4Vector4(items, OpenTK.Graphics.OpenGL4.PrimitiveType.Triangles, GLRenderState.Tri(), shape, starposbuf, ic: currentfilteredlist.Count, seconddivisor: 1);

                // Sun names, handled by textrenderer
                textrenderer = new GLBitmaps("bm-travelmap", rObjects, new Size(128, 40), depthtest: depthtest, cullface: false);
                items.Add(textrenderer);
            }
            else
            {
                tapepointbuf.AllocateFill(tape.Item1.ToArray());                                       // replace the points with a new one
                ritape.RenderState.PrimitiveRestart = GL4Statics.DrawElementsRestartValue(tape.Item3); // IMPORTANT missing bit Robert, must set the primitive restart value to the new tape size
                ritape.CreateElementIndex(ritape.ElementBuffer, tape.Item2.ToArray(), tape.Item3);     // update the element buffer
                ritape.Visible = tape.Item1.Count > 0;

                starposbuf.AllocateFill(positionsv4);           // and update the star position buffers so find and sun renderer works
                renderersun.InstanceCount = positionsv4.Length; // update the number of suns to draw.

                rifind.InstanceCount = positionsv4.Length;      // update the find list
            }

            // name bitmaps

            HashSet <object> hashset = new HashSet <object>(currentfilteredlist);       // so it can find it quickly

            textrenderer.CurrentGeneration++;                                           // setup for next generation
            textrenderer.RemoveGeneration(textrenderer.CurrentGeneration - 1, hashset); // and remove all of the previous one which are not in hashset.

            Font fnt = new Font("Arial", 8.5F);

            using (StringFormat fmt = new StringFormat())
            {
                fmt.Alignment = StringAlignment.Center;
                foreach (var isys in currentfilteredlist)
                {
                    if (textrenderer.Exist(isys) == false)                   // if does not exist already, need a new label
                    {
                        textrenderer.Add(isys, isys.System.Name, fnt, Color.White, Color.Transparent, new Vector3((float)isys.System.X, (float)isys.System.Y - 5, (float)isys.System.Z),
                                         new Vector3(20, 0, 0), new Vector3(0, 0, 0), textformat: fmt, rotatetoviewer: true, rotateelevation: false, alphafadescalar: -200, alphafadepos: 300);
                    }
                }
            }

            fnt.Dispose();
        }
        /// <summary>
        /// Creator of this draw set
        /// </summary>
        /// <param name="textures"> number of 2D textures to allow maximum (limited by GL)</param>
        /// <param name="estimateditemspergroup">Estimated objects per group, this adds on vertext buffer space to allow for mat4 alignment. Smaller means more allowance.</param>
        /// <param name="mingroups">Minimum groups to have</param>
        /// <param name="objectbuffer">Object buffer to use</param>
        /// <param name="objectvertexes">Number of object vertexes</param>
        /// <param name="objrc">The object render state control</param>
        /// <param name="objpt">The object draw primitive type</param>
        /// <param name="texturesize">The size of the label</param>
        /// <param name="textrc">The text render state</param>
        /// <param name="textureformat">The texture format for the text</param>
        /// <param name="debuglimittexture">For debug, set this to limit maximum number of entries. 0 = off</param>
        /// <returns></returns>
        public Tuple <GLRenderableItem, GLRenderableItem> Create(
            int textures,
            int estimateditemspergroup,
            int mingroups,
            GLBuffer objectbuffer, int objectvertexes, GLRenderState objrc, PrimitiveType objpt,
            Size texturesize, GLRenderState textrc, SizedInternalFormat textureformat,
            int debuglimittexture = 0)
        {
            this.objectvertexescount = objectvertexes;
            this.context             = GLStatics.GetContext();

            // Limit number of 2d textures in a single 2d array
            int maxtextper2darray = GL4Statics.GetMaxTextureDepth();

            if (debuglimittexture > 0)
            {
                maxtextper2darray = debuglimittexture;
            }

            // set up number of textmaps bound
            int maxtexturesbound = GL4Statics.GetMaxFragmentTextures();
            int textmaps         = Math.Min(textures, maxtexturesbound);

            // which then give us the number of stars we can do
            int objectcount = textmaps * maxtextper2darray;
            int groupcount  = objectcount / estimateditemspergroup;

            groupcount = Math.Max(mingroups, groupcount);               // min groups

            // System.Diagnostics.Debug.WriteLine($"GLObjectWithLabels oc {objectcount} gc {groupcount}");

            // estimate maximum vert buffer needed, allowing for extra due to the need to align the mat4
            int vertbufsize = objectcount * (GLBuffer.Vec4size + GLBuffer.Mat4size) + // for a vec4 + mat4 per object
                              groupcount * GLBuffer.Mat4size;                         // and for groupcount Mat4 fragmentation per group

            // create the vertex indirect buffer
            dataindirectbuffer = new GLVertexBufferIndirect(items, vertbufsize, GLBuffer.WriteIndirectArrayStride * groupcount, true, BufferUsageHint.DynamicDraw);

            // objects
            ObjectRenderer = GLRenderableItem.CreateVector4Vector4(items, objpt, objrc,
                                                                   objectbuffer, 0, 0,           // binding 0 is shapebuf, offset 0, no draw count yet
                                                                   dataindirectbuffer.Vertex, 0, // binding 1 is vertex's world positions, offset 0
                                                                   null, 0, 1);                  // no ic, second divisor 1
            ObjectRenderer.BaseIndexOffset      = 0;                                             // offset in bytes where commands are stored
            ObjectRenderer.MultiDrawCountStride = GLBuffer.WriteIndirectArrayStride;

            // text

            this.textures = new GLTexture2DArray[textmaps];

            for (int i = 0; i < this.textures.Length; i++)
            {
                int n = Math.Min(objectcount, maxtextper2darray);
                this.textures[i] = new GLTexture2DArray(texturesize.Width, texturesize.Height, n, textureformat, 1);
                items.Add(this.textures[i]);
                objectcount -= maxtextper2darray;
            }

            TextRenderer = GLRenderableItem.CreateMatrix4(items, PrimitiveType.Quads, textrc,
                                                          dataindirectbuffer.Vertex, 0, 0,           //attach buffer with matrices, no draw count
                                                          new GLRenderDataTexture(this.textures, 0), // binding 0 assign to our texture 2d
                                                          0, 1);                                     //no ic, and matrix divide so 1 matrix per vertex set
            TextRenderer.BaseIndexOffset      = 0;                                                   // offset in bytes where commands are stored
            TextRenderer.MultiDrawCountStride = GLBuffer.WriteIndirectArrayStride;


            return(new Tuple <GLRenderableItem, GLRenderableItem>(ObjectRenderer, TextRenderer));
        }
Exemplo n.º 3
0
        public void CreateObjects(GLItemsList items, GLRenderProgramSortedList rObjects, GalacticMapping galmap, GLStorageBlock findbufferresults, bool depthtest)
        {
            this.galmap = galmap;

            // first gets the images and make a 2d array texture for them

            Bitmap[] images = galmap.RenderableMapTypes.Select(x => x.Image as Bitmap).ToArray();
            // 256 is defined normal size
            var        objtex   = new GLTexture2DArray(images, bmpmipmaplevels: 1, wantedmipmaplevels: 3, texturesize: new Size(256, 256), internalformat: OpenTK.Graphics.OpenGL4.SizedInternalFormat.Rgba8, alignment: ContentAlignment.BottomCenter);
            IGLTexture texarray = items.Add(objtex, "GalObjTex");

            // now build the shaders

            const int texbindingpoint = 1;
            var       vert            = new GLPLVertexScaleLookat(rotatetoviewer: dorotate, rotateelevation: doelevation, // a look at vertex shader
                                                                  autoscale: 500, autoscalemin: 1f, autoscalemax: 20f);   // below 500, 1f, above 500, scale up to 20x
            var tcs = new GLPLTesselationControl(40f);

            tes = new GLPLTesselationEvaluateSinewave(1f, 2f);                  // this uses the world position from the vertex scaler to position the image, w controls image + animation (b16)
            var frag = new GLPLFragmentShaderTexture2DDiscard(texbindingpoint); // binding - takes image pos from tes. imagepos < 0 means discard

            objectshader = new GLShaderPipeline(vert, tcs, tes, null, frag);
            items.Add(objectshader);

            objectshader.StartAction += (s, m) =>
            {
                texarray.Bind(texbindingpoint);   // bind tex array to, matching above
            };

            // now the RenderControl for the objects

            GLRenderState rt = GLRenderState.Patches(4);

            rt.DepthTest = depthtest;

            // create a quad and all entries of the renderable map objects, zero at this point, with a zero instance count. UpdateEnables will fill it in later
            // but we need to give it the maximum buffer length at this point

            const float objsize = 10.0f;        // size of object on screen

            ridisplay = GLRenderableItem.CreateVector4Vector4(items, OpenTK.Graphics.OpenGL4.PrimitiveType.Patches, rt,
                                                              GLShapeObjectFactory.CreateQuadTriStrip(objsize, objsize), // quad2 4 vertexts
                                                              new Vector4[galmap.RenderableMapObjects.Length],           // world positions
                                                              ic: 0, seconddivisor: 1);

            modelworldbuffer = items.LastBuffer();
            int modelpos = modelworldbuffer.Positions[0];

            worldpos = modelworldbuffer.Positions[1];

            rObjects.Add(objectshader, "galmapobj", ridisplay);

            // add a find shader to look them up

            var geofind = new GLPLGeoShaderFindTriangles(findbufferresults, 16);

            findshader = items.NewShaderPipeline(null, vert, tcs, tes, geofind, null, null, null);


            // hook to modelworldbuffer, at modelpos and worldpos.  UpdateEnables will fill in instance count
            rifind = GLRenderableItem.CreateVector4Vector4(items, OpenTK.Graphics.OpenGL4.PrimitiveType.Patches, GLRenderState.Patches(4), modelworldbuffer, modelpos, ridisplay.DrawCount,
                                                           modelworldbuffer, worldpos, null, ic: 0, seconddivisor: 1);

            GLStatics.Check();

            // Text renderer for the labels

            textrenderer = new GLBitmaps("bm-galmapobjects", rObjects, new Size(128, 40), depthtest: depthtest, cullface: false, textureformat: OpenTK.Graphics.OpenGL4.SizedInternalFormat.Rgba8);
            items.Add(textrenderer);

            // now make the text up for all the objects above

            using (Font fnt = new Font("Arial", 8.5F))
            {
                using (StringFormat fmt = new StringFormat())
                {
                    fmt.Alignment = StringAlignment.Center;

                    var renderablegalmapobjects = galmap.RenderableMapObjects; // list of enabled entries

                    List <Vector3> posset = new List <Vector3>();

                    float offscale = objsize * (0.5f + (float)textrenderer.BitmapSize.Height / (float)textrenderer.BitmapSize.Width / 2);       // this is the nominal centre of the text bitmap, offset in Y to the object

                    for (int i = 0; i < renderablegalmapobjects.Length; i++)
                    {
                        var   o      = renderablegalmapobjects[i];
                        float offset = -offscale;

                        for (int j = 0; j < i; j++)     // look up previous ones and see if we labeled it before
                        {
                            var d1   = new Vector3(o.points[0].X, o.points[0].Y + offset, o.points[0].Z);
                            var d2   = posset[j];   // where it was placed.
                            var diff = d1 - d2;

                            if (diff.Length < offscale) // close
                            {
                                if (offset > 0)         // if offset is positive, flip below and increase again
                                {
                                    offset = -offset - offscale;
                                }
                                else
                                {
                                    offset *= -1;       // flip over top
                                }
                                // System.Diagnostics.Debug.WriteLine($"close {renderablegalmapobjects[i].name} {d1} to {renderablegalmapobjects[j].name} {d2} {diff} select {offset}");
                            }
                        }

                        Vector3 pos = new Vector3(o.points[0].X, o.points[0].Y + offset, o.points[0].Z);
                        posset.Add(pos);
                        //System.Diagnostics.Debug.WriteLine($"{renderablegalmapobjects[i].name} at {pos} {offset}");

                        textrenderer.Add(o.id, o.name, fnt,
                                         Color.White, Color.FromArgb(0, 255, 0, 255),
                                         pos,
                                         new Vector3(objsize, 0, 0), new Vector3(0, 0, 0), textformat: fmt, rotatetoviewer: dorotate, rotateelevation: doelevation,
                                         alphafadescalar: -100, alphafadepos: 500); // fade in, alpha = 0 at >500, 1 at 400
                    }
                }
            }

            UpdateEnables();      // fill in worldpos's and update instance count, taking into
        }
Exemplo n.º 4
0
        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  = 1000f;
            gl3dcontroller.ZoomDistance = 20F;
            gl3dcontroller.Start(glwfc, new Vector3(0, 0, 0), new Vector3(110f, 0, 0f), 1F);
            glwfc.MouseClick += GLMouseClick;

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

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

            #region coloured lines

            if (true)
            {
                GLRenderState lines = GLRenderState.Lines(1);

                rObjects.Add(items.Shader("COSW"),
                             GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Lines, lines,
                                                                  GLShapeObjectFactory.CreateLines(new Vector3(-100, -0, -100), new Vector3(-100, -0, 100), new Vector3(10, 0, 0), 21),
                                                                  new Color4[] { Color.Red, Color.Red, Color.DarkRed, Color.DarkRed })
                             );


                rObjects.Add(items.Shader("COSW"),
                             GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Lines, lines,
                                                                  GLShapeObjectFactory.CreateLines(new Vector3(-100, -0, -100), new Vector3(100, -0, -100), new Vector3(0, 0, 10), 21),
                                                                  new Color4[] { Color.Red, Color.Red, Color.DarkRed, Color.DarkRed }));
            }

            #endregion

            #region Coloured triangles
            if (true)
            {
                GLRenderState rc = GLRenderState.Tri();
                rc.CullFace = false;

                rObjects.Add(items.Shader("COSOT"), "scopen",
                             GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Triangles, rc,
                                                                  GLCubeObjectFactory.CreateSolidCubeFromTriangles(5f),
                                                                  new Color4[] { Color4.Red, Color4.Green, Color4.Blue, Color4.White, Color4.Cyan, Color4.Orange },
                                                                  new GLRenderDataTranslationRotation(new Vector3(10, 0, 20))
                                                                  ));
            }

            #endregion

            var sunvertex = new GLPLVertexShaderModelCoordWorldAutoscale(new Color[] { Color.FromArgb(255, 220, 220, 10), Color.FromArgb(255, 0, 0, 0) });
            items.Add(sunvertex);
            var sunshader = new GLShaderPipeline(sunvertex, new GLPLStarSurfaceFragmentShader());
            items.Add(sunshader);
            var shapebuf = new GLBuffer();
            items.Add(shapebuf);
            var shape = GLSphereObjectFactory.CreateSphereFromTriangles(1, 0.5f);
            shapebuf.AllocateFill(shape);

            GLStorageBlock block = new GLStorageBlock(20);
            findshader = items.NewShaderPipeline(null, sunvertex, null, null, new GLPLGeoShaderFindTriangles(block, 16), null, null, null);

            int texunitspergroup = 16;      // opengl minimum texture units per frag shader

            //var textshader = new GLShaderPipeline(new GLPLVertexShaderQuadTextureWithMatrixTranslation(), new GLPLFragmentShaderTexture2DIndexedMulti(0,0,true, texunitspergroup));
            var textshader = new TextShader(texunitspergroup);
            items.Add(textshader);
            Font fnt = new Font("MS sans serif", 16f);

            if (true)
            {
                int maxstars = 1000;    // this is an aspriation, depends on fragmentation of the system

                dataindirectbuffer = new GLVertexBufferIndirect(items, maxstars * (GLBuffer.Vec4size + GLBuffer.Mat4size), GLBuffer.WriteIndirectArrayStride * 100, true);
                var textarray = new GLTexture2DArray(128, 32, maxstars, SizedInternalFormat.Rgba8);

                int SectorSize = 10;

                {
                    Vector3   pos   = new Vector3(-20, 0, -15);
                    Vector4[] array = new Vector4[10];
                    Random    rnd   = new Random(23);
                    for (int i = 0; i < array.Length; i++)
                    {
                        array[i] = new Vector4(pos.X + rnd.Next(SectorSize), pos.Y + rnd.Next(SectorSize), pos.Z + rnd.Next(SectorSize), 0);
                    }
                    dataindirectbuffer.Fill(array, 0, array.Length, 0, shape.Length, 0, array.Length, -1);

                    Matrix4[] matrix = new Matrix4[array.Length];
                    for (int i = 0; i < array.Length; i++)
                    {
                        int imgpos = textarray.DepthIndex;
                        textarray.DrawText("A" + i, fnt, Color.White, Color.Blue, -1);
                        var mat = GLPLVertexShaderMatrixQuadTexture.CreateMatrix(new Vector3(array[i].X, array[i].Y + 0.6f, array[i].Z),
                                                                                 new Vector3(1, 0, 0.2f),
                                                                                 new Vector3(-90F.Radians(), 0, 0),
                                                                                 imagepos: imgpos);
                        matrix[i] = mat;
                    }

                    dataindirectbuffer.Vertex.AlignMat4();          // instancing counts in mat4 sizes (mat4 0 @0, mat4 1 @ 64 etc) so align to it
                    dataindirectbuffer.Fill(matrix, 0, matrix.Length, 1, 4, 0, array.Length, -1);
                }

                if (true)
                {
                    Vector3   pos   = new Vector3(-20, 0, 0);
                    Vector4[] array = new Vector4[5];
                    Random    rnd   = new Random(23);
                    for (int i = 0; i < array.Length; i++)
                    {
                        array[i] = new Vector4(pos.X + rnd.Next(SectorSize), pos.Y + rnd.Next(SectorSize), pos.Z + rnd.Next(SectorSize), 0);
                    }
                    dataindirectbuffer.Fill(array, 0, array.Length, 0, shape.Length, 0, array.Length, -1);
                }

                if (true)
                {
                    Vector3   pos   = new Vector3(-20, 0, 15);
                    Vector4[] array = new Vector4[10];
                    Random    rnd   = new Random(23);
                    for (int i = 0; i < array.Length; i++)
                    {
                        array[i] = new Vector4(pos.X + rnd.Next(SectorSize), pos.Y + rnd.Next(SectorSize), pos.Z + rnd.Next(SectorSize), 0);
                    }
                    dataindirectbuffer.Fill(array, 0, array.Length, 0, shape.Length, 0, array.Length, -1);

                    Matrix4[] matrix = new Matrix4[array.Length];
                    for (int i = 0; i < array.Length; i++)
                    {
                        int imgpos = textarray.DepthIndex;
                        textarray.DrawText("C" + i, fnt, Color.White, Color.Red, -1);
                        var mat = GLPLVertexShaderMatrixQuadTexture.CreateMatrix(new Vector3(array[i].X, array[i].Y + 0.6f, array[i].Z),
                                                                                 new Vector3(1, 0, 0.2f),
                                                                                 new Vector3(-90F.Radians(), 0, 0),
                                                                                 imagepos: imgpos);
                        matrix[i] = mat;
                    }

                    dataindirectbuffer.Vertex.AlignMat4();          // instancing countis in mat4 sizes (mat4 0 @0, mat4 1 @ 64 etc) so align to it
                    dataindirectbuffer.Fill(matrix, 0, matrix.Length, 1, 4, 0, array.Length, -1);
                }


                int[]   indirectints0 = dataindirectbuffer.Indirects[0].ReadInts(0, 12);
                int[]   indirectints1 = dataindirectbuffer.Indirects[1].ReadInts(0, 4);
                float[] worldpos      = dataindirectbuffer.Vertex.ReadFloats(0, 3 * 2 * 4);

                if (true)
                {
                    GLRenderState rt = GLRenderState.Tri();     // render is triangles, with no depth test so we always appear
                    rt.DepthTest  = true;
                    rt.DepthClamp = true;

                    var renderer = GLRenderableItem.CreateVector4Vector4(items, PrimitiveType.Triangles, rt,
                                                                         shapebuf, 0, 0,               // binding 0 is shapebuf, offset 0, no draw count
                                                                         dataindirectbuffer.Vertex, 0, // binding 1 is vertex's world positions, offset 0
                                                                         null, 0, 1);                  // no ic, second divisor 1
                    renderer.IndirectBuffer       = dataindirectbuffer.Indirects[0];
                    renderer.BaseIndexOffset      = 0;                                                 // offset in bytes where commands are stored
                    renderer.DrawCount            = 3;
                    renderer.MultiDrawCountStride = GLBuffer.WriteIndirectArrayStride;

                    rObjects.Add(sunshader, "sunshader", renderer);
                }

                if (true)
                {
                    var rc = GLRenderState.Quads();
                    rc.CullFace           = true;
                    rc.DepthTest          = true;
                    rc.ClipDistanceEnable = 1;  // we are going to cull primitives which are deleted

                    var renderer = GLRenderableItem.CreateMatrix4(items, PrimitiveType.Quads, rc,
                                                                  dataindirectbuffer.Vertex, 0, 0, //attach buffer with matrices, no draw count
                                                                  new GLRenderDataTexture(textarray, 0),
                                                                  0, 1);                           //no ic, and matrix divide so 1 matrix per vertex set
                    renderer.IndirectBuffer       = dataindirectbuffer.Indirects[1];
                    renderer.BaseIndexOffset      = 0;                                             // offset in bytes where commands are stored
                    renderer.DrawCount            = 2;
                    renderer.MultiDrawCountStride = GLBuffer.WriteIndirectArrayStride;

                    rObjects.Add(textshader, "textshader", renderer);
                }
            }

            if (true)
            {
                GLRenderState starrc = GLRenderState.Tri();     // render is triangles, with no depth test so we always appear
                starrc.DepthTest  = true;
                starrc.DepthClamp = true;

                var textrc = GLRenderState.Quads();
                textrc.DepthTest          = true;
                textrc.ClipDistanceEnable = 1;  // we are going to cull primitives which are deleted

                sl = new GLObjectsWithLabels();
                var ris = sl.Create(texunitspergroup, 50, 50, shapebuf, shape.Length, starrc, PrimitiveType.Triangles, new Size(128, 32), textrc, SizedInternalFormat.Rgba8, 3);
                rObjects.Add(sunshader, "SLsunshade", ris.Item1);
                rObjects.Add(textshader, "SLtextshade", ris.Item2);
                items.Add(sl);

                int SectorSize = 10;
                {
                    Vector3   pos   = new Vector3(0, 0, -15);
                    Vector4[] array = new Vector4[10];
                    string[]  text  = new string[array.Length];
                    Random    rnd   = new Random(31);
                    for (int i = 0; i < array.Length; i++)
                    {
                        array[i] = new Vector4(pos.X + rnd.Next(SectorSize), pos.Y + rnd.Next(SectorSize), pos.Z + rnd.Next(SectorSize), 0);
                        text[i]  = "A.r" + i;
                    }

                    var mats = GLPLVertexShaderMatrixQuadTexture.CreateMatrices(array, new Vector3(0, 0.6f, 0), new Vector3(2f, 0, 0.4f), new Vector3(-90F.Radians(), 0, 0), true, false);
                    var bmps = GLOFC.Utils.BitMapHelpers.DrawTextIntoFixedSizeBitmaps(sl.LabelSize, text, fnt, System.Drawing.Text.TextRenderingHint.ClearTypeGridFit, Color.White, Color.DarkBlue, 0.5f);

                    List <GLObjectsWithLabels.BlockRef> bref = new List <GLObjectsWithLabels.BlockRef>();
                    sl.Add(array, mats, bmps, bref);
                    GLOFC.Utils.BitMapHelpers.Dispose(bmps);
                }
                {
                    Vector3   pos   = new Vector3(0, 0, 0);
                    Vector4[] array = new Vector4[20];
                    string[]  text  = new string[array.Length];
                    Random    rnd   = new Random(31);
                    for (int i = 0; i < array.Length; i++)
                    {
                        array[i] = new Vector4(pos.X + rnd.Next(SectorSize), pos.Y + rnd.Next(SectorSize), pos.Z + rnd.Next(SectorSize), 0);
                        text[i]  = "B." + i;
                    }

                    List <GLObjectsWithLabels.BlockRef> bref = new List <GLObjectsWithLabels.BlockRef>();
                    sl.Add(array, text, fnt, Color.White, Color.DarkBlue, new Vector3(2f, 0, 0.4f), new Vector3(-90F.Radians(), 0, 0), true, false, null, 0.5f, new Vector3(0, 0.6f, 0), bref);
                }
                {
                    Vector3   pos   = new Vector3(0, 0, 15);
                    Vector4[] array = new Vector4[10];
                    string[]  text  = new string[array.Length];
                    Random    rnd   = new Random(31);
                    for (int i = 0; i < array.Length; i++)
                    {
                        array[i] = new Vector4(pos.X + rnd.Next(SectorSize), pos.Y + rnd.Next(SectorSize), pos.Z + rnd.Next(SectorSize), 0);
                        text[i]  = "C." + i;
                    }

                    List <GLObjectsWithLabels.BlockRef> bref = new List <GLObjectsWithLabels.BlockRef>();
                    sl.Add(array, text, fnt, Color.White, Color.DarkBlue, new Vector3(2f, 0, 0.4f), new Vector3(-90F.Radians(), 0, 0), true, false, null, 0.5f, new Vector3(0, 0.6f, 0), bref);
                }

                System.Diagnostics.Debug.WriteLine($"Sets {sl.Blocks} Removed {sl.BlocksRemoved}");
            }

            // Sets of..

            if (true)
            {
                GLRenderState starrc = GLRenderState.Tri();     // render is triangles, with no depth test so we always appear
                starrc.DepthTest  = true;
                starrc.DepthClamp = true;

                var textrc = GLRenderState.Quads();
                textrc.DepthTest          = true;
                textrc.ClipDistanceEnable = 1;  // we are going to cull primitives which are deleted

                slset = new GLSetOfObjectsWithLabels("SLSet", rObjects, true ? 4 : texunitspergroup,
                                                     50, 10,
                                                     sunshader, shapebuf, shape.Length, starrc, PrimitiveType.Triangles,
                                                     textshader, new Size(128, 32), textrc, SizedInternalFormat.Rgba8,
                                                     3);
                items.Add(slset);

                int SectorSize = 10;
                {
                    Vector3   pos   = new Vector3(20, 0, -15);
                    Vector4[] array = new Vector4[10];
                    string[]  text  = new string[array.Length];
                    Random    rnd   = new Random(31);
                    for (int i = 0; i < array.Length; i++)
                    {
                        array[i] = new Vector4(pos.X + rnd.Next(SectorSize), pos.Y + rnd.Next(SectorSize), pos.Z + rnd.Next(SectorSize), 0);
                        text[i]  = "S.A.r" + i;
                    }

                    var mats = GLPLVertexShaderMatrixQuadTexture.CreateMatrices(array, new Vector3(0, 0.6f, 0), new Vector3(2f, 0, 0.4f), new Vector3(-90F.Radians(), 0, 0), true, false);
                    var bmps = GLOFC.Utils.BitMapHelpers.DrawTextIntoFixedSizeBitmaps(slset.LabelSize, text, fnt, System.Drawing.Text.TextRenderingHint.ClearTypeGridFit, Color.White, Color.DarkBlue, 0.5f);

                    slset.Add("GA", text, array, mats, bmps);
                    GLOFC.Utils.BitMapHelpers.Dispose(bmps);
                }
                {
                    Vector3   pos   = new Vector3(20, 0, 0);
                    Vector4[] array = new Vector4[10];
                    string[]  text  = new string[array.Length];
                    Random    rnd   = new Random(31);
                    for (int i = 0; i < array.Length; i++)
                    {
                        array[i] = new Vector4(pos.X + rnd.Next(SectorSize), pos.Y + rnd.Next(SectorSize), pos.Z + rnd.Next(SectorSize), 0);
                        text[i]  = "S.B." + i;
                    }

                    var mats = GLPLVertexShaderMatrixQuadTexture.CreateMatrices(array, new Vector3(0, 0.6f, 0), new Vector3(2f, 0, 0.4f), new Vector3(-90F.Radians(), 0, 0), true, false);
                    var bmps = GLOFC.Utils.BitMapHelpers.DrawTextIntoFixedSizeBitmaps(slset.LabelSize, text, fnt, System.Drawing.Text.TextRenderingHint.ClearTypeGridFit, Color.White, Color.DarkBlue, 0.5f);

                    slset.Add("GB", text, array, mats, bmps);
                    GLOFC.Utils.BitMapHelpers.Dispose(bmps);
                }
                {
                    Vector3   pos   = new Vector3(20, 0, 15);
                    Vector4[] array = new Vector4[10];
                    string[]  text  = new string[array.Length];
                    Random    rnd   = new Random(31);
                    for (int i = 0; i < array.Length; i++)
                    {
                        array[i] = new Vector4(pos.X + rnd.Next(SectorSize), pos.Y + rnd.Next(SectorSize), pos.Z + rnd.Next(SectorSize), 0);
                        text[i]  = "S.C." + i;
                    }

                    var mats = GLPLVertexShaderMatrixQuadTexture.CreateMatrices(array, new Vector3(0, 0.6f, 0), new Vector3(2f, 0, 0.4f), new Vector3(-90F.Radians(), 0, 0), true, false);
                    var bmps = GLOFC.Utils.BitMapHelpers.DrawTextIntoFixedSizeBitmaps(slset.LabelSize, text, fnt, System.Drawing.Text.TextRenderingHint.ClearTypeGridFit, Color.White, Color.DarkBlue, 0.5f);

                    slset.Add("GC", text, array, mats, bmps);
                    GLOFC.Utils.BitMapHelpers.Dispose(bmps);
                }
            }

            #region Matrix Calc Uniform

            items.Add(new GLMatrixCalcUniformBlock(), "MCUB");     // def binding of 0

            #endregion
        }
Exemplo n.º 5
0
        // Demonstrate buffer feedback AND geo shader add vertex/dump vertex



        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            Closed += ShaderTest_Closed;

            gl3dcontroller = new Controller3D();
            gl3dcontroller.PaintObjects = ControllerDraw;
            gl3dcontroller.ZoomDistance = 20F;
            gl3dcontroller.MatrixCalc.PerspectiveNearZDistance = 0.1f;
            glwfc.BackColor = Color.FromArgb(0, 0, 60);
            gl3dcontroller.Start(glwfc, new Vector3(0, 0, 0), new Vector3(120f, 0, 0f), 1F);

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

            items.Add(new GLMatrixCalcUniformBlock(), "MCUB");      // def binding of 0

            {
                items.Add(new GLColorShaderWorld(), "COS");
                GLRenderState rl = GLRenderState.Lines(1);

                rObjects.Add(items.Shader("COS"),
                             GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Lines, rl,
                                                                  GLShapeObjectFactory.CreateLines(new Vector3(-40, 0, -40), new Vector3(-40, 0, 40), new Vector3(10, 0, 0), 9),
                                                                  new Color4[] { Color.Red, Color.Red, Color.Green, Color.Green })
                             );


                rObjects.Add(items.Shader("COS"),
                             GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Lines, null,
                                                                  GLShapeObjectFactory.CreateLines(new Vector3(-40, 0, -40), new Vector3(40, 0, -40), new Vector3(0, 0, 10), 9),
                                                                  new Color4[] { Color.Red, Color.Red, Color.Green, Color.Green })
                             );
            }

            {
                items.Add(new GLTexturedShaderObjectTranslation(), "TEX");
                items.Add(new GLTexture2D(Properties.Resources.moonmap1k, SizedInternalFormat.Rgba8), "moon");

                GLRenderState rt = GLRenderState.Tri();

                rObjects.Add(items.Shader("TEX"), "sphere7",
                             GLRenderableItem.CreateVector4Vector2(items, PrimitiveType.Triangles, rt,
                                                                   GLSphereObjectFactory.CreateTexturedSphereFromTriangles(4, 10.0f),
                                                                   new GLRenderDataTranslationRotationTexture(items.Tex("moon"), new Vector3(-30, 0, 0))
                                                                   ));
            }

            {
                var sunvertex = new GLPLVertexShaderModelCoordWorldAutoscale(new Color[] { Color.Yellow, Color.FromArgb(255, 230, 230, 1) });

                items.Add(new GLShaderPipeline(sunvertex, new GLPLStarSurfaceFragmentShader()), "STAR");

                GLRenderState rt = GLRenderState.Tri();

                rObjects.Add(items.Shader("STAR"), "sun",
                             GLRenderableItem.CreateVector4(items, PrimitiveType.Triangles,
                                                            rt,
                                                            GLSphereObjectFactory.CreateSphereFromTriangles(3, 10.0f),
                                                            new GLRenderDataTranslationRotation(new Vector3(20, 0, 0)),
                                                            ic: 1));

                items.Add(new GLShaderStarCorona(), "CORONA");

                GLRenderState rq = GLRenderState.Quads();

                rObjects.Add(items.Shader("CORONA"), GLRenderableItem.CreateVector4(items, PrimitiveType.Quads,
                                                                                    rq,
                                                                                    GLShapeObjectFactory.CreateQuad(1f),
                                                                                    new GLRenderDataTranslationRotation(new Vector3(20, 0, 0), new Vector3(0, 0, 0), 20f, calclookat: true)));
            }

            if (true)
            {
                Vector4[] pos = new Vector4[3];
                pos[0] = new Vector4(-20, 0, 10, 0);
                pos[1] = new Vector4(0, 0, 10, 1);
                pos[2] = new Vector4(20, 0, 10, 2);

                var shape = GLSphereObjectFactory.CreateSphereFromTriangles(3, 10.0f);

                GLRenderState    rt = GLRenderState.Tri();
                GLRenderableItem ri = GLRenderableItem.CreateVector4Vector4(items, PrimitiveType.Triangles, rt, shape, pos, null, pos.Length, 1);

                var vertshader = new GLPLVertexShaderModelCoordWorldAutoscale(new Color[] { Color.Red, Color.Green, Color.Blue });
                var shader     = new GLShaderPipeline(vertshader, new GLPLStarSurfaceFragmentShader());
                items.Add(shader, "STAR-M2");
                rObjects.Add(shader, ri);
            }

            GLOFC.GLStatics.Check();

            GL.Enable(EnableCap.DepthClamp);
        }
Exemplo n.º 6
0
        public void Start(string name, int maxstars, float sunsize, float tapesize, GLStorageBlock bufferfindresults, bool depthtest, GLItemsList items, GLRenderProgramSortedList rObjects)
        {
            this.MaxStars = maxstars;
            this.tapesize = tapesize;
            this.sunsize  = sunsize;

            // first the tape

            var tapetex = new GLTexture2D(BaseUtils.Icons.IconSet.GetBitmap("GalMap.chevron"), internalformat: OpenTK.Graphics.OpenGL4.SizedInternalFormat.Rgba8);        // tape image

            items.Add(tapetex);
            tapetex.SetSamplerMode(OpenTK.Graphics.OpenGL4.TextureWrapMode.Repeat, OpenTK.Graphics.OpenGL4.TextureWrapMode.Repeat);

            // configure the fragger, set the replacement color, and set the distance where the replacement color is used for all pixels
            tapefrag = new GLPLFragmentShaderTextureTriStripColorReplace(1, Color.FromArgb(255, 206, 0, 0), 1000);
            // create the vertex shader with the autoscale required
            var vert = new GLPLVertexShaderWorldTextureTriStripNorm(100, 1, 10000);

            vert.SetWidth(tapesize);        // set the nominal tape width

            tapeshader = new GLShaderPipeline(vert, tapefrag);
            items.Add(tapeshader);

            GLRenderState rts = GLRenderState.Tri(OpenTK.Graphics.OpenGL4.DrawElementsType.UnsignedByte, cullface: false); // set up a Tri strip, Default primitive restart

            rts.DepthTest = depthtest;                                                                                     // no depth test so always appears

            // now the renderer, set up with the render control, tape as the points, and bind a RenderDataTexture so the texture gets binded each time

            var zerotape = new Vector4[] { Vector4.Zero };      // just use an dummy array to get this going

            ritape = GLRenderableItem.CreateVector4Vector4(items, OpenTK.Graphics.OpenGL4.PrimitiveType.TriangleStrip, rts, zerotape, zerotape, new GLRenderDataTexture(tapetex));

            tapepointbuf = items.LastBuffer();                // keep buffer for refill

            ritape.ElementBuffer = items.NewBuffer();         // empty buffer for element index for now
            ritape.Visible       = false;                     // until its filled, not visible (important, we don't want render to execute unless its been fully set up below)

            rObjects.Add(tapeshader, name + "-tape", ritape); // add render to object list

            // now the stars

            starposbuf = items.NewBuffer();         // where we hold the vertexes for the suns, used by renderer and by finder

            // the colour index of the stars is selected by the w parameter of the world position vertexes.
            // we autoscale to make them bigger at greater distances from eye
            sunvertex = new GLPLVertexShaderModelCoordWorldAutoscale(new Color[] { Color.Yellow, Color.FromArgb(255, 230, 230, 1) },
                                                                     autoscale: 30, autoscalemin: 1, autoscalemax: 2, useeyedistance: false);
            sunshader = new GLShaderPipeline(sunvertex, new GLPLStarSurfaceFragmentShader());
            items.Add(sunshader);

            var shape = GLSphereObjectFactory.CreateSphereFromTriangles(2, sunsize);

            GLRenderState rt = GLRenderState.Tri();     // render is triangles, with no depth test so we always appear

            rt.DepthTest        = depthtest;
            rt.DepthClamp       = true;
            renderersun         = GLRenderableItem.CreateVector4Vector4(items, OpenTK.Graphics.OpenGL4.PrimitiveType.Triangles, rt, shape, starposbuf, 0, null, 0, 1);
            renderersun.Visible = false;            // until its filled, not visible

            rObjects.Add(sunshader, name + "-suns", renderersun);

            // find compute

            var geofind = new GLPLGeoShaderFindTriangles(bufferfindresults, 16);

            findshader = items.NewShaderPipeline(null, sunvertex, null, null, geofind, null, null, null);
            rifind     = GLRenderableItem.CreateVector4Vector4(items, OpenTK.Graphics.OpenGL4.PrimitiveType.Triangles, GLRenderState.Tri(), shape, starposbuf, ic: 0, seconddivisor: 1);

            // Sun names, handled by textrenderer
            textrenderer = new GLBitmaps(name + "-text", rObjects, BitMapSize, depthtest: depthtest, cullface: false);
            items.Add(textrenderer);
        }