Пример #1
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="name">Name of bitmap collection</param>
        /// <param name="rlist">Render list to draw into</param>
        /// <param name="bitmapsize">Bit map size</param>
        /// <param name="mipmaplevels">Mip map levels</param>
        /// <param name="textureformat">Texture format of bitmaps</param>
        /// <param name="cullface">True to cull face</param>
        /// <param name="depthtest">True to depth test</param>
        /// <param name="maxpergroup">Maximum number of bitmaps per group</param>
        /// <param name="yfixed">Set true to fix Y co-ord externally</param>
        public GLBitmaps(string name, GLRenderProgramSortedList rlist, Size bitmapsize, int mipmaplevels = 3,
                         OpenTK.Graphics.OpenGL4.SizedInternalFormat textureformat = OpenTK.Graphics.OpenGL4.SizedInternalFormat.Rgba8,
                         bool cullface = true, bool depthtest = true, int maxpergroup = int.MaxValue, bool yfixed = false)
        {
            this.name    = name;
            this.context = GLStatics.GetContext();

            int maxdepthpertexture = GL4Statics.GetMaxTextureDepth();   // limits the number of textures per 2darray
            int max = Math.Min(maxdepthpertexture, maxpergroup);        //note RI uses a VertexArray to load the matrix in, so not limited by that (max size of uniform buffer)

            matrixbuffers = new GLSetOfMatrixBufferWithGenerations(items, max);

            matrixbuffers.AddedNewGroup += AddedNewGroup;       // hook up call back to say i've made a group

            renderlist      = rlist;
            this.bitmapsize = bitmapsize;

            shader = new GLShaderPipeline(new GLPLVertexShaderMatrixQuadTexture(yfixed), new GLPLFragmentShaderTexture2DIndexed(0, alphablend: true));
            items.Add(shader);

            renderstate                    = GLRenderState.Quads();
            renderstate.CullFace           = cullface;
            renderstate.DepthTest          = depthtest;
            renderstate.ClipDistanceEnable = 1;  // we are going to cull primitives which are deleted

            texmipmaplevels    = mipmaplevels;
            this.textureformat = textureformat;
        }
        } = new Dictionary <object, object>();                                                            // tag to user data, optional

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="name">Name of set</param>
        /// <param name="rlist">Render list to draw into</param>
        /// <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 number of groups</param>
        /// <param name="objectshader">Shader for objects</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="textshader">Text shader for labels</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="debuglimittexturedepth">For debug, set this to limit maximum number of entries. 0 = off</param>
        public GLSetOfObjectsWithLabels(string name,
                                        GLRenderProgramSortedList rlist,
                                        int textures,
                                        int estimateditemspergroup,
                                        int mingroups,                                                                                                      // minimum number of groups
                                        IGLProgramShader objectshader, GLBuffer objectbuffer, int objectvertexes, GLRenderState objrc, PrimitiveType objpt, // object shader, buffer, vertexes and its rendercontrol
                                        IGLProgramShader textshader, Size texturesize, GLRenderState textrc, SizedInternalFormat textureformat,             // text shader, text size, and rendercontrol
                                        int debuglimittexturedepth = 0)                                                                                     // set to limit texture depth per set
        {
            this.name     = name;
            this.robjects = rlist;
            this.textures = textures;
            this.estimateditemspergroup = estimateditemspergroup;
            this.mingroups           = mingroups;
            this.objectshader        = objectshader;
            this.objectbuffer        = objectbuffer;
            this.objectvertexescount = objectvertexes;
            this.objrc             = objrc;
            this.objpt             = objpt;
            this.textshader        = textshader;
            this.texturesize       = texturesize;
            this.textrc            = textrc;
            this.textureformat     = textureformat;
            this.limittexturedepth = debuglimittexturedepth;
        }
Пример #3
0
        public void Create(GLItemsList items, GLRenderProgramSortedList rObjects, float sunsize, GLStorageBlock findbufferresults)
        {
            sunvertex = new GLPLVertexShaderModelCoordWorldAutoscale(new Color[] { Color.FromArgb(255, 220, 220, 10), Color.FromArgb(255, 0, 0, 0) },
                                                                     autoscale: 30, autoscalemin: 1, autoscalemax: 2, useeyedistance: false);
            sunshader = items.NewShaderPipeline(null, sunvertex, new GLPLStarSurfaceFragmentShader());

            shapebuf = items.NewBuffer(false);
            var shape = GLSphereObjectFactory.CreateSphereFromTriangles(2, sunsize);

            shapebuf.AllocateFill(shape);

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

            starrc.DepthTest  = true;
            starrc.DepthClamp = true;

            var textrc = GLRenderState.Tri();

            textrc.DepthTest          = true;
            textrc.ClipDistanceEnable = 1;  // we are going to cull primitives which are deleted

            int texunitspergroup = 16;

            textshader = items.NewShaderPipeline(null, new GLPLVertexShaderMatrixTriStripTexture(), new GLPLFragmentShaderTexture2DIndexMulti(0, 0, true, texunitspergroup));

            slset = new GLSetOfObjectsWithLabels("SLSet", rObjects, texunitspergroup, 100, 10,
                                                 sunshader, shapebuf, shape.Length, starrc, OpenTK.Graphics.OpenGL4.PrimitiveType.Triangles,
                                                 textshader, BitMapSize, textrc, SizedInternalFormat.Rgba8);

            items.Add(slset);

            var geofind = new GLPLGeoShaderFindTriangles(findbufferresults, 16);

            findshader = items.NewShaderPipeline(null, sunvertex, null, null, geofind, null, null, null);
        }
        // tested to 50K+ stars, tested updating a single one

        public void Create(GLItemsList items, GLRenderProgramSortedList rObjects, List <HistoryEntry> incomingsys, float sunsize, float tapesize,
                           GLStorageBlock bufferfindresults, bool depthtest)
        {
            this.sunsize   = sunsize;
            this.tapesize  = tapesize;
            this.depthtest = depthtest;

            unfilteredlist = incomingsys;

            IntCreatePath(items, rObjects, bufferfindresults);
        }
        public void Create(GLItemsList items, GLRenderProgramSortedList rObjects, List <SystemClass> incomingsys, float bookmarksize, GLStorageBlock findbufferresults, bool depthtest)
        {
            if (ridisplay == null)
            {
                //var vert = new GLPLVertexScaleLookat(rotate: dorotate, rotateelevation: doelevation, commontransform: false, texcoords: true,      // a look at vertex shader
                //
                //                var vert = new GLPLVertexShaderWorldCoord();
                var vert = new GLPLVertexScaleLookat(rotatetoviewer: dorotate, rotateelevation: doelevation, texcoords: true, generateworldpos: true,
                                                     autoscale: 500, autoscalemin: 1f, autoscalemax: 20f);            // below 500, 1f, above 500, scale up to 20x


                const int texbindingpoint = 1;
                var       frag            = new GLPLFragmentShaderTexture(texbindingpoint); // binding - simple texturer based on vs model coords

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

                var objtex = items.NewTexture2D("Bookmarktex", TestOpenTk.Properties.Resources.dotted2, OpenTK.Graphics.OpenGL4.SizedInternalFormat.Rgba8);

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

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

                GLRenderState rt = GLRenderState.Tri();
                rt.DepthTest = depthtest;

                bookmarksize *= 10;

                // 0 is model pos, 1 is world pos by a buffer, 2 is tex co-ords
                ridisplay = GLRenderableItem.CreateVector4Vector4Vector2(items, OpenTK.Graphics.OpenGL4.PrimitiveType.TriangleStrip, rt,
                                                                         GLShapeObjectFactory.CreateQuadTriStrip(bookmarksize, bookmarksize), // quad2 4 vertexts as the model positions
                                                                         bookmarkposbuf, 0,                                                   // world positions come from here - not filled as yet
                                                                         GLShapeObjectFactory.TexTriStripQuad,
                                                                         ic: 0, seconddivisor: 1);

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

                var geofind = new GLPLGeoShaderFindTriangles(findbufferresults, 16);//, forwardfacing:false);
                findshader = items.NewShaderPipeline(null, vert, null, null, geofind, null, null, null);

                // hook to modelworldbuffer, at modelpos and worldpos.  UpdateEnables will fill in instance count
                rifind = GLRenderableItem.CreateVector4Vector4Vector2(items, OpenTK.Graphics.OpenGL4.PrimitiveType.TriangleStrip, rt,
                                                                      GLShapeObjectFactory.CreateQuadTriStrip(bookmarksize, bookmarksize),   // quad2 4 vertexts as the model positions
                                                                      bookmarkposbuf, 0,
                                                                      GLShapeObjectFactory.TexTriStripQuad,
                                                                      ic: 0, seconddivisor: 1);
            }

            bookmarkposbuf.AllocateFill(incomingsys.Select(x => new Vector4((float)x.X, (float)x.Y, (float)x.Z, 1)).ToArray());
            ridisplay.InstanceCount = rifind.InstanceCount = incomingsys.Count;
        }
Пример #6
0
        public void Start(GLItemsList items, GLRenderProgramSortedList rObjects, float bookmarksize, GLStorageBlock findbufferresults, bool depthtest)
        {
            var vert = new GLPLVertexScaleLookat(rotatetoviewer: dorotate, rotateelevation: doelevation, texcoords: true, generateworldpos: true,
                                                 autoscale: 30, autoscalemin: 1f, autoscalemax: 30f);            // above autoscale, 1f

            const int texbindingpoint = 1;
            var       frag            = new GLPLFragmentShaderTexture(texbindingpoint); // binding - simple texturer based on vs model coords

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

            var objtex = items.NewTexture2D("Bookmarktex", BaseUtils.Icons.IconSet.GetBitmap("GalMap.Bookmark"), OpenTK.Graphics.OpenGL4.SizedInternalFormat.Rgba8);

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

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

            GLRenderState rt = GLRenderState.Tri();

            rt.DepthTest = depthtest;

            // 0 is model pos, 1 is world pos by a buffer, 2 is tex co-ords
            ridisplay = GLRenderableItem.CreateVector4Vector4Vector2(items, OpenTK.Graphics.OpenGL4.PrimitiveType.TriangleStrip, rt,
                                                                     GLShapeObjectFactory.CreateQuadTriStrip(bookmarksize, bookmarksize), // quad2 4 vertexts as the model positions
                                                                     bookmarkposbuf, 0,                                                   // world positions come from here - not filled as yet
                                                                     GLShapeObjectFactory.TexTriStripQuad,
                                                                     ic: 0, seconddivisor: 1);

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

            var geofind = new GLPLGeoShaderFindTriangles(findbufferresults, 16);//, forwardfacing:false);

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

            // hook to modelworldbuffer, at modelpos and worldpos.  UpdateEnables will fill in instance count
            rifind = GLRenderableItem.CreateVector4Vector4Vector2(items, OpenTK.Graphics.OpenGL4.PrimitiveType.TriangleStrip, rt,
                                                                  GLShapeObjectFactory.CreateQuadTriStrip(bookmarksize, bookmarksize),   // quad2 4 vertexts as the model positions
                                                                  bookmarkposbuf, 0,
                                                                  GLShapeObjectFactory.TexTriStripQuad,
                                                                  ic: 0, seconddivisor: 1);
        }
        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();
        }
Пример #8
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
        }
        public void CreateObjects(string name, GLItemsList items, GLRenderProgramSortedList rObjects, GalacticMapping galmap, float sizeofname = 5000, ManualCorrections[] corr = null)
        {
            List <Vector4> vertexcolourregions      = new List <Vector4>();
            List <Vector4> vertexregionsoutlines    = new List <Vector4>();
            List <ushort>  vertexregionoutlineindex = new List <ushort>();

            Size bitmapsize = new Size(250, 22);

            textrenderer = new GLBitmaps(name + "-bitmaps", rObjects, bitmapsize, depthtest: false, yfixed: true);
            items.Add(textrenderer);

            StringFormat fmt = new StringFormat(StringFormatFlags.NoWrap)
            {
                Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center
            };
            Font fnt = new Font("MS Sans Serif", 12F);

            int cindex = 0;

            foreach (GalacticMapObject gmo in galmap.galacticMapObjects)
            {
                if (gmo.galMapType.Group == GalMapType.GalMapGroup.Regions)
                {
                    string gmoname = gmo.name;

                    List <Vector2> polygonxz = new List <Vector2>();                              // needs it in x/z and in vector2's
                    foreach (var pd in gmo.points)
                    {
                        polygonxz.Add(new Vector2((float)pd.X, (float)pd.Z));                   // can be concave and wound the wrong way..
                        vertexregionoutlineindex.Add((ushort)(vertexregionsoutlines.Count));
                        vertexregionsoutlines.Add(new Vector4((float)pd.X, 0, (float)pd.Z, 1));
                    }

                    vertexregionoutlineindex.Add(0xffff);                                             // primitive restart to break polygon

                    List <List <Vector2> > polys = PolygonTriangulator.Triangulate(polygonxz, false); // cut into convex polygons first - because we want the biggest possible area for naming purposes

                    Vector2 avgcentroid    = new Vector2(0, 0);
                    int     pointsaveraged = 0;

                    if (polys.Count > 0)                                                 // just in case..
                    {
                        foreach (List <Vector2> points in polys)                         // now for every poly
                        {
                            List <List <Vector2> > polytri;
                            if (points.Count == 3)                                    // already a triangle..
                            {
                                polytri = new List <List <Vector2> >()
                                {
                                    new List <Vector2>()
                                    {
                                        points[0], points[1], points[2]
                                    }
                                }
                            }
                            ;
                            else
                            {
                                polytri = PolygonTriangulator.Triangulate(points, true);    // cut into triangles not polygons
                            }
                            foreach (List <Vector2> pt in polytri)
                            {
                                vertexcolourregions.Add(pt[0].ToVector4XZ(w: cindex));
                                vertexcolourregions.Add(pt[2].ToVector4XZ(w: cindex));
                                vertexcolourregions.Add(pt[1].ToVector4XZ(w: cindex));

                                var cx = (pt[0].X + pt[1].X + pt[2].X) / 3;
                                var cy = (pt[0].Y + pt[1].Y + pt[2].Y) / 3;
                                avgcentroid = new Vector2(avgcentroid.X + cx, avgcentroid.Y + cy);
                                pointsaveraged++;

                                //foreach (var pd in pt) // debug
                                //{
                                //    vertexregionoutlineindex.Add((ushort)(vertexregionsoutlines.Count));
                                //    vertexregionsoutlines.Add(new Vector4((float)pd.X, 0, (float)pd.Y, 1));
                                //}
                                //vertexregionoutlineindex.Add(0xffff);       // primitive restart to break polygon
                            }
                        }

                        cindex = (cindex + 1) % array.Length;

                        Vector2 centeroid = PolygonTriangulator.WeightedCentroids(polys);

                        if (corr != null)   // allows the centeroid to be nerfed slightly
                        {
                            var entry = Array.Find(corr, x => gmo.name.Contains(x.name, StringComparison.InvariantCultureIgnoreCase));
                            if (entry != null)
                            {
                                centeroid = new Vector2(centeroid.X + entry.x, centeroid.Y + entry.y);
                            }
                        }

                        var final = PolygonTriangulator.FitInsideConvexPoly(polys, centeroid, new Vector2(sizeofname, sizeofname * (float)bitmapsize.Height / (float)bitmapsize.Width));

                        Vector3 bestpos  = new Vector3(final.Item1.X, 0, final.Item1.Y);
                        Vector3 bestsize = new Vector3(final.Item2.X, 1, final.Item2.Y);

                        textrenderer.Add(null, gmo.name, fnt, Color.White, Color.Transparent, bestpos, bestsize, new Vector3(0, 0, 0), fmt, alphafadescalar: 5000, alphafadepos: 500);
                    }
                }
            }

            fmt.Dispose();
            fnt.Dispose();

            // regions

            var vertregion = new GLPLVertexShaderWorldPalletColor(array.ToVector4(0.1f), true);
            var fragregion = new GLPLFragmentShaderVSColor();

            regionshader = new GLShaderPipeline(vertregion, fragregion, null, null);
            items.Add(regionshader);

            GLRenderState rt = GLRenderState.Tri();

            rt.DepthTest = false;
            var ridisplay = GLRenderableItem.CreateVector4(items, OpenTK.Graphics.OpenGL4.PrimitiveType.Triangles, rt, vertexcolourregions.ToArray());

            rObjects.Add(regionshader, name + "-regions", ridisplay);

            // outlines

            var vertoutline = new GLPLVertexShaderWorldCoord(true);
            var fragoutline = new GLPLFragmentShaderFixedColor(Color.Cyan);

            outlineshader = new GLShaderPipeline(vertoutline, fragoutline, null, null);
            items.Add(outlineshader);

            GLRenderState ro = GLRenderState.Lines();

            ro.DepthTest        = false;
            ro.PrimitiveRestart = 0xffff;
            var rioutline = GLRenderableItem.CreateVector4(items, OpenTK.Graphics.OpenGL4.PrimitiveType.LineStrip, ro, vertexregionsoutlines.ToArray());

            rioutline.CreateElementIndexUShort(items.NewBuffer(), vertexregionoutlineindex.ToArray());

            rObjects.Add(outlineshader, name + "-outlines", rioutline);

            renderstate = 7;
        }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="itemlist">Item list to store object onto</param>
        /// <param name="renderlist">Render list to add renders to</param>

        public GLWavefrontObjCreator(GLItemsList itemlist, GLRenderProgramSortedList renderlist)
        {
            items = itemlist;
            rlist = renderlist;
        }
Пример #11
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);
        }