// returns GMO, and z - if not found z = Max value, null public GalacticMapObject FindPOI(Point viewportloc, GLRenderState state, Size viewportsize, out float z) { z = float.MaxValue; if (Enable) { var geo = findshader.GetShader <GLPLGeoShaderFindTriangles>(OpenTK.Graphics.OpenGL4.ShaderType.GeometryShader); geo.SetScreenCoords(viewportloc, viewportsize); rifind.Execute(findshader, state); // execute, discard var res = geo.GetResult(); if (res != null) { var renderablegalmapobjects = galmap.VisibleMapObjects; // list of displayable entries int index = 0; foreach (var o in renderablegalmapobjects) { bool en = GetGalObjectTypeEnable(o.GalMapType.TypeName); // we need to account for ones not enabled, since we rewrite the model buffer list on each enable if (en) { if (index == (int)res[0].Y) { z = res[0].Z; return(o); } index++; } } } } return(null); }
public object Find(Point loc, GLRenderState state, Size viewportsize, out float z) { z = 0; if (!objectshader.Enable) { return(null); } var geo = findshader.GetShader <GLPLGeoShaderFindTriangles>(OpenTK.Graphics.OpenGL4.ShaderType.GeometryShader); geo.SetScreenCoords(loc, viewportsize); rifind.Execute(findshader, state); // execute. Geoshader discards geometry by not outputting anything var res = geo.GetResult(); if (res != null) { for (int i = 0; i < res.Length; i++) { System.Diagnostics.Debug.WriteLine($"bk {i} {res[i]}"); } z = res[0].Z; return(null); } return(null); }
protected override void OnLoad(EventArgs e) { base.OnLoad(e); Closed += ShaderTest_Closed; gl3dcontroller = new Controller3D(); gl3dcontroller.PaintObjects = ControllerDraw; gl3dcontroller.MatrixCalc.PerspectiveNearZDistance = 0.1f; gl3dcontroller.ZoomDistance = 20F; gl3dcontroller.Start(glwfc, new Vector3(0, 0, 0), new Vector3(110f, 0, 0f), 1F); gl3dcontroller.KeyboardTravelSpeed = (ms, eyedist) => { return((float)ms / 50.0f); }; //items.Add("lensflarewhite", new GLTexture2D(Properties.Resources.lensflare_white64)); items.Add(new GLTexture2D(Properties.Resources.StarFlare2, SizedInternalFormat.Rgba8), "lensflare"); items.Add(new GLColorShaderWorld(), "COS"); #region coloured lines { GLRenderState rl = GLRenderState.Lines(1); rObjects.Add(items.Shader("COS"), // horizontal GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Lines, rl, 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.Green, Color.Green }) ); rObjects.Add(items.Shader("COS"), // vertical GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Lines, rl, 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.Green, Color.Green }) ); } var p = GLPointsFactory.RandomStars4(100, -100, 100, 100, -100, 100, -100); //p = new Vector4[10]; //for( int i = 0; i < 10; i++) //{ // p[i] = new Vector4(i, 6.8f, 0,1); //} items.Add(new GLPointSprite(), "PS1"); GLRenderState rp = GLRenderState.PointSprites(); // by program GLRenderDataTexture rt = new GLRenderDataTexture(items.Tex("lensflare"), 4); rObjects.Add(items.Shader("PS1"), GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Points, rp, p, new Color4[] { Color.Red, Color.Yellow, Color.Green }, rt)); #endregion items.Add(new GLMatrixCalcUniformBlock(), "MCUB"); // create a matrix uniform block }
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); }
/// <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; }
// returns HE, and z - if not found z = Max value, null public Object FindSystem(Point viewportloc, GLRenderState state, Size viewportsize, out float z) { z = float.MaxValue; if (EnableStars && findshader.Compiled && (currentfilteredlistsys?.Count ?? 0) > 0) { var geo = findshader.GetShader <GLPLGeoShaderFindTriangles>(OpenTK.Graphics.OpenGL4.ShaderType.GeometryShader); geo.SetScreenCoords(viewportloc, viewportsize); rifind.Execute(findshader, state); // execute, discard var res = geo.GetResult(); if (res != null) { //for (int i = 0; i < res.Length; i++) System.Diagnostics.Debug.WriteLine(i + " = " + res[i]); z = res[0].Z; int index = (int)res[0].Y; if (index < currentfilteredlistsys.Count) { if (currentfilteredlisthe != null && index < currentfilteredlisthe.Count) // #3266 has an exception here, no idea why, since sys+he should be the same length { return(currentfilteredlisthe[index]); } else { return(currentfilteredlistsys[index]); } } } } return(null); }
/// <summary> /// Find object on screen /// </summary> /// <param name="findshader">The shader to use for the find</param> /// <param name="glstate">Render state</param> /// <param name="pos">Position on screen of find point</param> /// <param name="size">Screen size</param> /// <returns>Return tuple of set, render group, render index in group, z of find, or null</returns> public Tuple <int, int, int, float> Find(GLShaderPipeline findshader, GLRenderState glstate, Point pos, Size size) { var geo = findshader.GetShader <GLPLGeoShaderFindTriangles>(OpenTK.Graphics.OpenGL4.ShaderType.GeometryShader); geo.SetScreenCoords(pos, size); findshader.Start(null); // this clears the buffer int setno = 0; foreach (var s in set) { geo.SetGroup(setno++ << 18); // set the group marker for this group as a uniform (encoded in drawID in .W) s.ObjectRenderer.Execute(findshader, glstate, noshaderstart: true); // execute find over ever set, not clearing the buffer } findshader.Finish(); // finish shader var res = geo.GetResult(); if (res != null) { System.Diagnostics.Debug.WriteLine("Set Found something"); for (int i = 0; i < res.Length; i++) { System.Diagnostics.Debug.WriteLine(i + " = " + res[i]); } return(new Tuple <int, int, int, float>(((int)res[0].W) >> 18, ((int)res[0].W) & 0x3ffff, (int)res[0].Y, res[0].Z)); } else { return(null); } }
// Find at point, return found and z point public GalacticMapObject FindPOI(Point loc, GLRenderState state, Size viewportsize, out float z) { z = 0; if (!objectshader.Enable) { return(null); } var geo = findshader.GetShader <GLPLGeoShaderFindTriangles>(OpenTK.Graphics.OpenGL4.ShaderType.GeometryShader); geo.SetScreenCoords(loc, viewportsize); GLStatics.Check(); rifind.Execute(findshader, state); // execute. Geoshader discards geometry by not outputting anything var res = geo.GetResult(); if (res != null) { // for (int i = 0; i < res.Length; i++) System.Diagnostics.Debug.WriteLine(i + " = " + res[i]); z = res[0].Z; int instance = (int)res[0].Y; // tbd wrong! not a one to one mapping return(galmap.RenderableMapObjects[indextoentry[instance]]); //TBD } return(null); }
// returns name only, and z - if not found z = Max value, null public SystemClass Find(Point loc, GLRenderState rs, Size viewportsize, out float z) { z = float.MaxValue; if (sunshader.Enable) { var find = slset.FindBlock(findshader, rs, loc, viewportsize); // return block tag, index, z if (find != null) { z = find.Item5; var userdata = slset.UserData[find.Item1[0].tag] as string[]; // System.Diagnostics.Debug.WriteLine($"SLSet {find.Item2} {find.Item3} {find.Item4} {find.Item5} {userdata[find.Item2]}"); string name = userdata[find.Item4]; int atsign = name.IndexOf(" @"); // remove any information denoted by space @ if (atsign >= 0) { name = name.Substring(0, atsign); } return(new SystemClass() { Name = name }); // without position note } } return(null); }
/// <summary> /// Construct a control display /// </summary> /// <param name="items">Items to store GL data to</param> /// <param name="win">GLWindowControl to hook to</param> /// <param name="mc">Matrix Calc to use</param> /// <param name="depthtest">Enable depth test</param> /// <param name="startz">Start Z for nearest top level window</param> /// <param name="deltaz">Delta Z between each top level window</param> /// <param name="arbbufferid">ARB buffer to use for texture bindless storage</param> public GLControlDisplay(GLItemsList items, GLWindowControl win, GLMatrixCalc mc, bool depthtest = true, // do depth testing or not float startz = 0.001f, // z for the deepest window (only will apply if depth testing float deltaz = 0.001f, // delta betwwen them int arbbufferid = 10 ) : base("displaycontrol", new Rectangle(0, 0, mc.ScreenCoordMax.Width, mc.ScreenCoordMax.Height)) { glwin = win; MatrixCalc = mc; context = GLStatics.GetContext(); this.items = items; vertexes = items.NewBuffer(); vertexarray = items.NewVertexArray(); vertexes.Bind(vertexarray, 0, 0, vertexesperentry * sizeof(float)); // bind to 0, from 0, 2xfloats. Must bind after vertexarray is made as its bound during construction vertexarray.Attribute(0, 0, vertexesperentry, OpenTK.Graphics.OpenGL4.VertexAttribType.Float); // bind 0 on attr 0, 2 components per vertex GLRenderState rc = GLRenderState.Tri(); rc.PrimitiveRestart = 0xff; rc.DepthTest = depthtest; this.startz = startz; this.deltaz = deltaz; ri = new GLRenderableItem(PrimitiveType.TriangleStrip, rc, 0, vertexarray); // create a renderable item ri.CreateRectangleElementIndexByte(items.NewBuffer(), 255 / 5); // note this limits top level controls number to 255/5. ri.DrawCount = 0; // nothing to draw at this point shader = new GLShaderPipeline(new GLPLVertexShaderScreenTexture(), new GLPLFragmentShaderBindlessTexture(arbbufferid, true, discardiftransparent: true)); items.Add(shader); textures = new Dictionary <GLBaseControl, GLTexture2D>(); size = new Dictionary <GLBaseControl, Size>(); visible = new Dictionary <GLBaseControl, bool>(); texturebinds = items.NewBindlessTextureHandleBlock(arbbufferid); glwin.MouseMove += Gc_MouseMove; glwin.MouseClick += Gc_MouseClick; glwin.MouseDoubleClick += Gc_MouseDoubleClick; glwin.MouseDown += Gc_MouseDown; glwin.MouseUp += Gc_MouseUp; glwin.MouseEnter += Gc_MouseEnter; glwin.MouseLeave += Gc_MouseLeave; glwin.MouseWheel += Gc_MouseWheel; glwin.KeyDown += Gc_KeyDown; glwin.KeyUp += Gc_KeyUp; glwin.KeyPress += Gc_KeyPress; glwin.Resize += Gc_Resize; glwin.Paint += Gc_Paint; suspendLayoutCount = 0; }
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; }
private void GLStore(ref GLRenderState glState) { if (glState.colorWriteMask == null) { glState.colorWriteMask = new bool[4]; } // Store OpenGL context GL.GetInteger(GetPName.UnpackAlignment, out glState.unpackAlignment); GL.GetBoolean(GetPName.ColorWritemask, glState.colorWriteMask); glState.blendEnabled = GL.IsEnabled(EnableCap.Blend); GL.GetBoolean(GetPName.StencilTest, out glState.stencilTestEnabled); }
// Demonstrate buffer feedback AND geo shader add vertex/dump vertex protected override void OnLoad(EventArgs e) { base.OnLoad(e); gl3dcontroller = new Controller3D(); gl3dcontroller.PaintObjects = ControllerDraw; gl3dcontroller.ZoomDistance = 20F; gl3dcontroller.MatrixCalc.PerspectiveNearZDistance = 0.1f; gl3dcontroller.Start(glwfc, new Vector3(0, 0, 0), new Vector3(170f, 0, 0f), 1F); gl3dcontroller.KeyboardTravelSpeed = (ms, eyedist) => { return((float)ms / 20.0f); }; // 16 vertexes, passed thru geo shader above GLStorageBlock storagebuffer = new GLStorageBlock(5); // new storage block on binding index 5 to provide vertexes Vector4[] vertexes = new Vector4[16]; for (int v = 0; v < vertexes.Length; v++) { vertexes[v] = new Vector4(v % 4, 0, v / 4, 1); } storagebuffer.AllocateFill(vertexes); items.Add(new ShaderT3(), "Shader"); // geo shader GLRenderState ri = GLRenderState.Points(); rObjects.Add(items.Shader("Shader"), "T1", new GLRenderableItem(PrimitiveType.Points, ri, vertexes.Length, null, null, 1)); // list of rejected by geoshader above rejectedbuffer = new GLStorageBlock(1); // new storage block on binding index 1 for vector out rejectedbuffer.AllocateBytes(sizeof(float) * 4 * 128, OpenTK.Graphics.OpenGL4.BufferUsageHint.DynamicCopy); // set size of vec buffer countbuffer = new GLStorageBlock(2); // new storage block on binding index 2 for count out countbuffer.AllocateBytes(sizeof(int), OpenTK.Graphics.OpenGL4.BufferUsageHint.DynamicRead); // set size to a int. // redrawer of rejected items items.Add(new GLShaderPipeline(new GLPLVertexShaderWorldCoord(), new GLPLFragmentShaderFixedColor(new Color4(0.9f, 0.0f, 0.0f, 1.0f))), "ResultShader"); GLRenderState rs = GLRenderState.Points(30); redraw = GLRenderableItem.CreateVector4(items, PrimitiveType.Points, rs, rejectedbuffer, 0); rObjects2.Add(items.Shader("ResultShader"), redraw); items.Add(new GLMatrixCalcUniformBlock(), "MCUB"); // def binding of 0 Closed += ShaderTest_Closed; }
private void GLRestore(ref GLRenderState glState) { #if ANDROID || __IOS__ GL.Oes.BindVertexArray(0); #elif !MAC GL.BindVertexArray(0); #endif GL.BindBuffer(BufferTarget.ArrayBuffer, 0); GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); // Unbind stuff if (this.disableSamplers) { for (int i = 0; i < this.maxTextureUnits; i++) { GL.ActiveTexture(TextureUnit.Texture0 + i); GL.BindTexture(TextureTarget.Texture2D, 0); #if ANDROID || __IOS__ OpenTK.Graphics.ES30.GL.BindSampler(i, 0); #elif !MAC GL.BindSampler(i, 0); #endif } } GL.UseProgram(0); // Restore OpenGL context GL.PixelStore(PixelStoreParameter.UnpackAlignment, glState.unpackAlignment); GL.ColorMask(glState.colorWriteMask[0], glState.colorWriteMask[1], glState.colorWriteMask[2], glState.colorWriteMask[3]); if (glState.blendEnabled) { GL.Enable(EnableCap.Blend); } else { GL.Disable(EnableCap.Blend); } if (glState.stencilTestEnabled) { GL.Enable(EnableCap.StencilTest); } else { GL.Disable(EnableCap.StencilTest); } }
protected override void OnLoad(EventArgs e) { base.OnLoad(e); Closed += ShaderTest_Closed; gl3dcontroller = new Controller3D(); gl3dcontroller.PaintObjects = ControllerDraw; gl3dcontroller.MatrixCalc.PerspectiveNearZDistance = 0.1f; gl3dcontroller.ZoomDistance = 20F; gl3dcontroller.Start(glwfc, new Vector3(0, 0, 0), new Vector3(110f, 0, 0f), 1F); gl3dcontroller.KeyboardTravelSpeed = (ms, eyedist) => { return((float)ms / 100.0f); }; items.Add(new GLColorShaderWorld(), "COSW"); GLRenderState rl1 = GLRenderState.Lines(1); { rObjects.Add(items.Shader("COSW"), "L1", // horizontal GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Lines, rl1, GLShapeObjectFactory.CreateLines(new Vector3(-100, 0, -100), new Vector3(-100, 0, 100), new Vector3(10, 0, 0), 21), new Color4[] { Color.Gray }) ); rObjects.Add(items.Shader("COSW"), // vertical GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Lines, rl1, GLShapeObjectFactory.CreateLines(new Vector3(-100, 0, -100), new Vector3(100, 0, -100), new Vector3(0, 0, 10), 21), new Color4[] { Color.Gray }) ); } items.Add(new GLTexture2D(Properties.Resources.galheightmap7, SizedInternalFormat.Rgba8), "gal"); items.Add(new GLGalShader(), "TEX-NC"); GLRenderState rg = GLRenderState.Quads(cullface: false); rObjects.Add(items.Shader("TEX-NC"), GLRenderableItem.CreateVector4Vector2(items, PrimitiveType.Quads, rg, GLShapeObjectFactory.CreateQuad(200.0f, 200.0f, new Vector3(0, 0, 0)), GLShapeObjectFactory.TexQuadCW, new GLRenderDataTranslationRotationTexture(items.Tex("gal"), new Vector3(0, 0, 0)) )); items.Add(new GLMatrixCalcUniformBlock(), "MCUB"); // create a matrix uniform block }
/// <summary> /// Find object on screen /// </summary> /// <param name="findshader">The shader to use for the find</param> /// <param name="glstate">Render state</param> /// <param name="pos">Position on screen of find point</param> /// <param name="size">Screen size</param> /// <returns>Return block list render group and index into it, or null</returns> public Tuple <int, int> Find(GLShaderPipeline findshader, GLRenderState glstate, Point pos, Size size) { var geo = findshader.GetShader <GLPLGeoShaderFindTriangles>(OpenTK.Graphics.OpenGL4.ShaderType.GeometryShader); geo.SetScreenCoords(pos, size); ObjectRenderer.Execute(findshader, glstate); var res = geo.GetResult(); if (res != null) { //System.Diagnostics.Debug.WriteLine("Set Found something"); for (int i = 0; i < res.Length; i++) System.Diagnostics.Debug.WriteLine(i + " = " + res[i]); return(new Tuple <int, int>((int)res[0].W, (int)res[0].Y)); } else { return(null); } }
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); }
// Find at point, return found and z point public HistoryEntry FindSystem(Point loc, GLRenderState state, Size viewportsize, out float z) { z = 0; var geo = findshader.GetShader <GLPLGeoShaderFindTriangles>(OpenTK.Graphics.OpenGL4.ShaderType.GeometryShader); geo.SetScreenCoords(loc, viewportsize); rifind.Execute(findshader, state); var res = geo.GetResult(); if (res != null) { z = res[0].Z; //for (int i = 0; i < res.Length; i++) System.Diagnostics.Debug.WriteLine(i + " = " + res[i]); return(currentfilteredlist[(int)res[0].Y]); } return(null); }
public SystemClass Find(Point loc, GLRenderState rs, Size viewportsize, out float z) { z = 0; var find = slset.FindBlock(findshader, rs, loc, viewportsize); if (find != null) { System.Diagnostics.Debug.WriteLine($"SLSet {find.Item2} {find.Item3} {find.Item4} {find.Item5}"); var userdata = slset.UserData[find.Item1[0].tag] as string[]; System.Diagnostics.Debug.WriteLine($"... {userdata[find.Item4]}"); return(new SystemClass() { Name = userdata[find.Item4] }); } else { return(null); } }
protected override void OnLoad(EventArgs e) { base.OnLoad(e); Closed += ShaderTest_Closed; gl3dcontroller = new Controller3D(); gl3dcontroller.PaintObjects = ControllerDraw; gl3dcontroller.MatrixCalc.PerspectiveNearZDistance = 0.1f; gl3dcontroller.ZoomDistance = 40F; gl3dcontroller.MouseRotateAmountPerPixel = 0.05f; gl3dcontroller.Start(glwfc, new Vector3(0, 0, 0), new Vector3(135, 0, 0), 1F); gl3dcontroller.KeyboardTravelSpeed = (ms, eyedist) => { return((float)ms / 100.0f); }; items.Add(new GLColorShaderWorld(), "COSW"); GLRenderState rl1 = GLRenderState.Lines(1); { rObjects.Add(items.Shader("COSW"), "L1", // horizontal GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Lines, rl1, GLShapeObjectFactory.CreateLines(new Vector3(-100, 0, -100), new Vector3(-100, 0, 100), new Vector3(10, 0, 0), 21), new Color4[] { Color.Gray }) ); rObjects.Add(items.Shader("COSW"), // vertical GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Lines, rl1, GLShapeObjectFactory.CreateLines(new Vector3(-100, 0, -100), new Vector3(100, 0, -100), new Vector3(0, 0, 10), 21), new Color4[] { Color.Gray }) ); } // Number markers using instancing and 2d arrays, each with its own transform { Bitmap[] numbers = new Bitmap[20]; Matrix4[] numberpos = new Matrix4[20]; Font fnt = new Font("Arial", 44); for (int i = 0; i < numbers.Length; i++) { int v = -100 + i * 10; 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(-80f.Radians()); numberpos[i] *= Matrix4.CreateTranslation(new Vector3(20, 0, v)); } 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(1.0f), GLShapeObjectFactory.TexQuadCW, numberpos, rt, numberpos.Length)); } { int left = -40, right = 40, bottom = -20, top = +20, front = -40, back = 40; 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)); } items.Add(new ShaderV2(), "V2"); Vector4[] points = new Vector4[] { new Vector4(-40, -20, -40, 1), new Vector4(+40, +20, +40, 1), }; GLRenderState rltot = GLRenderState.Tri(); rObjects.Add(items.Shader("V2"), GLRenderableItem.CreateVector4(items, PrimitiveType.Lines, rltot, points, ic: 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); }
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(); }
protected override void OnLoad(EventArgs e) { base.OnLoad(e); Closed += ShaderTest_Closed; items.Add(new GLMatrixCalcUniformBlock(), "MCUB"); // create a matrix uniform block int front = -20000, back = front + 90000, left = -45000, right = left + 90000, vsize = 2000; 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 GLFixedShader(System.Drawing.Color.Yellow), "LINEYELLOW"); rObjects.Add(items.Shader("LINEYELLOW"), GLRenderableItem.CreateVector4(items, PrimitiveType.Lines, rl, displaylines)); } float h = 0; if (h != -1) { items.Add(new GLColorShaderWorld(), "COS-1L"); int dist = 1000; 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 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 Color4[] { cr }) ); } GLMatrixCalc mc = new GLMatrixCalc(); mc.PerspectiveNearZDistance = 1f; mc.PerspectiveFarZDistance = 500000f; mc.ResizeViewPort(this, glwfc.Size); // must establish size before starting displaycontrol = new GLControlDisplay(items, glwfc, mc); // hook form to the window - its the master, it takes its size fro mc.ScreenCoordMax displaycontrol.Focusable = true; // we want to be able to focus and receive key presses. displaycontrol.Name = "displaycontrol"; displaycontrol.Font = new Font("Times", 8); GLForm pform = new GLForm("Form1", "GL Form demonstration", new Rectangle(0, 0, 1000, 800)); int taborder = 0; if (true) { string l = "Hello there ggg qqq jjj" + Environment.NewLine + "And the ggg next line"; GLMultiLineTextBox mtb = new GLMultiLineTextBox("mltb", new Rectangle(10, 10, 400, 200), l); mtb.Font = new Font("Ms Sans Serif", 24.25f); //mtb.Font = new Font("Arial", 25f); mtb.LineColor = Color.Green; mtb.EnableVerticalScrollBar = true; mtb.EnableHorizontalScrollBar = true; mtb.SetSelection(16 * 2 + 2, 16 * 3 + 4); mtb.TabOrder = taborder++; mtb.RightClickMenuFont = new Font("Euro Caps", 14f); mtb.FlashingCursor = false; pform.Add(mtb); } if (true) { string l = ""; for (int i = 0; i < 5; i++) { string s = string.Format("Line " + i); if (i == 0) { s += "And a much much longer Line which should break the width"; } l += s + "\r\n"; } l += "trail "; // l = ""; GLMultiLineTextBox mtb = new GLMultiLineTextBox("mltb", new Rectangle(0, 400, 400, 200), l); mtb.Font = new Font("Ms Sans Serif", 16); mtb.LineColor = Color.Green; mtb.EnableVerticalScrollBar = true; mtb.EnableHorizontalScrollBar = true; mtb.SetSelection(16 * 2 + 2, 16 * 3 + 4); mtb.TabOrder = taborder++; mtb.RightClickMenuFont = new Font("Euro Caps", 14f); pform.Add(mtb); //mtb.FlashingCursor = false; //mtb.ReadOnly = true; GLMultiLineTextBox mtb2 = new GLMultiLineTextBox("mltb2", new Rectangle(500, 400, 495, 200), l); mtb2.Font = new Font("Ms Sans Serif", 11); mtb2.LineColor = Color.Green; mtb2.EnableVerticalScrollBar = true; mtb2.EnableHorizontalScrollBar = true; mtb2.SetSelection(16 * 2 + 2, 16 * 3 + 4); mtb2.TabOrder = taborder++; mtb2.RightClickMenuFont = new Font("Arial", 14f); pform.Add(mtb2); } if (true) { GLTextBox tb1 = new GLTextBox("TB1", new Rectangle(0, 300, 350, 40), "Text Box Which is a very long string of very many many characters"); tb1.Font = new Font("Arial", 12); tb1.ReturnPressed += (c1) => { System.Diagnostics.Debug.WriteLine($"Return pressed on text box"); }; tb1.TabOrder = taborder++; pform.Add(tb1); } displaycontrol.Add(pform); gl3dcontroller = new Controller3D(); gl3dcontroller.ZoomDistance = 5000F; gl3dcontroller.YHoldMovement = true; gl3dcontroller.PaintObjects = Controller3dDraw; gl3dcontroller.KeyboardTravelSpeed = (ms, eyedist) => { return((float)ms * 10.0f); }; gl3dcontroller.MatrixCalc.InPerspectiveMode = true; if (displaycontrol != null) { gl3dcontroller.Start(mc, displaycontrol, new Vector3(0, 0, 10000), new Vector3(140.75f, 0, 0), 0.5F); // HOOK the 3dcontroller to the form so it gets Form events displaycontrol.Paint += (o, ts) => // subscribing after start means we paint over the scene, letting transparency work { displaycontrol.Render(glwfc.RenderState, ts); // we use the same matrix calc as done in controller 3d draw }; } else { gl3dcontroller.Start(glwfc, new Vector3(0, 0, 10000), new Vector3(140.75f, 0, 0), 0.5F); // HOOK the 3dcontroller to the form so it gets Form events } systemtimer.Start(); }
protected override void OnLoad(EventArgs e) { base.OnLoad(e); Closed += ShaderTest_Closed; items.Add(new GLMatrixCalcUniformBlock(), "MCUB"); // create a matrix uniform block int front = -20000, back = front + 90000, left = -45000, right = left + 90000, vsize = 2000; 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 GLFixedShader(System.Drawing.Color.Yellow), "LINEYELLOW"); rObjects.Add(items.Shader("LINEYELLOW"), GLRenderableItem.CreateVector4(items, PrimitiveType.Lines, rl, displaylines)); } float h = 0; if (h != -1) { items.Add(new GLColorShaderWorld(), "COS-1L"); int dist = 1000; 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 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 Color4[] { cr }) ); } GLMatrixCalc mc = new GLMatrixCalc(); mc.PerspectiveNearZDistance = 1f; mc.PerspectiveFarZDistance = 500000f; if (true) { bool testform1 = true; mc.ResizeViewPort(this, glwfc.Size); // must establish size before starting displaycontrol = new GLControlDisplay(items, glwfc, mc); // hook form to the window - its the master, it takes its size fro mc.ScreenCoordMax displaycontrol.Focusable = true; // we want to be able to focus and receive key presses. displaycontrol.Name = "displaycontrol"; if (testform1) { GLForm pform = new GLForm("Form1", "GL Menu demonstration", new Rectangle(10, 10, 600, 200)); displaycontrol.Add(pform); if (true) { GLMenuStrip menubar = new GLMenuStrip("Menubar", new Rectangle(0, 0, 500, 24)); menubar.AutoOpenDelay = 1000; menubar.Font = new Font("Euro Caps", 12); menubar.Dock = DockingType.Top; menubar.SubMenuBorderWidth = 1; GLMenuItem l1 = new GLMenuItem("MI-0A", "MenuA"); menubar.Add(l1); GLMenuItem l1a = new GLMenuItem("A-1", "MenuA-1"); GLMenuItem l1b = new GLMenuItem("A-2", "MenuA-2"); l1b.CheckOnClick = true; l1b.Checked = true; GLMenuItem l1c = new GLMenuItem("A-3", "MenuA-3") { Image = Properties.Resources.GoToHomeSystem }; l1c.CheckOnClick = true; l1.SubMenuItems = new List <GLBaseControl>() { l1a, l1b, l1c }; GLMenuItem l1a1 = new GLMenuItem("A-1-1", "MenuA-1-1"); GLMenuItem l1a2 = new GLMenuItem("A-1-2", "MenuA-1-2"); GLMenuItem l1a21 = new GLMenuItem("A-1-2-1", "MenuA-1-2-1"); GLMenuItem l1a22 = new GLMenuItem("A-1-2-2", "MenuA-1-2-2"); l1a2.SubMenuItems = new List <GLBaseControl>() { l1a21, l1a22 }; GLCheckBox l1a3 = new GLCheckBox("A-1-3", new Rectangle(0, 0, 0, 0), "CheckBox A-1-3"); l1a3.CheckOnClick = true; l1a3.CheckChanged += (bc) => { menubar.CloseMenus(); }; // need to associate check changed with closing menus - optional GLComboBox l1a4 = new GLComboBox("A-1-4", new Rectangle(0, 0, 0, 0), new List <string>() { "one", "two", "three" }); l1a4.SelectedIndexChanged += (c) => { menubar.CloseMenus(); }; l1a4.DisableChangeKeys = true; l1a.SubMenuItems = new List <GLBaseControl>() { l1a1, l1a2, l1a3, l1a4 }; GLMenuItem l2 = new GLMenuItem("MI-0B", "MenuB"); menubar.Add(l2); GLMenuItem l2a = new GLMenuItem("B-1", "MenuB-1"); l2a.Click += (s) => { System.Diagnostics.Debug.WriteLine("Clicked Menu " + s.Name); }; GLMenuItem l2b = new GLMenuItem("B-2", "MenuB-2"); l2.SubMenuItems = new List <GLBaseControl>() { l2a, l2b }; GLMenuItem l3 = new GLMenuItem("MI-0C", "MenuC"); menubar.Add(l3); pform.Add(menubar); } } if (true) { GLContextMenu ctx1, ctx2; ctx1 = new GLContextMenu("CM1"); GLMenuItem cm1 = new GLMenuItem("CM1A", "Menu-1"); cm1.CheckOnClick = true; GLMenuItem cm2 = new GLMenuItem("CM1B", "Menu-2"); cm2.CheckOnClick = true; GLMenuItem cm3 = new GLMenuItem("CM1C", "Menu-3"); GLMenuItem l1a1 = new GLMenuItem("CM1C-1", "Menu-1-1"); l1a1.CheckOnClick = true; GLMenuItem l1a2 = new GLMenuItem("CM1C-2", "MenuA-1-2"); GLCheckBox l1a3 = new GLCheckBox("CM1C-3", new Rectangle(0, 0, 0, 0), "CheckBox A-1-3"); l1a3.CheckOnClick = true; cm3.SubMenuItems = new List <GLBaseControl>() { l1a1, l1a2, l1a3 }; int count = 0; ctx1.Opening += (c1, c2) => { bool on = count++ % 2 == 0; System.Diagnostics.Debug.WriteLine($"Set cm2 state {on}"); cm2.Visible = on; }; ctx1.Add(cm1); ctx1.Add(cm2); ctx1.Add(cm3); Color tc = Color.Orange; ctx2 = new GLContextMenu("CM1", new GLMenuItem[] { new GLMenuItem("CM1A", "MenuR1") { CheckOnClick = true, ForeColor = tc }, new GLMenuItem("CM1B", "MenuR2") { CheckOnClick = true, Enabled = false, ForeColor = tc }, new GLMenuItem("CM1C", "MenuR3") { CheckOnClick = true }, new GLMenuItem("CM1C", "MenuR4") { CheckOnClick = true }, new GLMenuItem("CM1C", "MenuR5") { }, }); ctx2.Font = new Font("Euro caps", 18f); displaycontrol.MouseClick += (s, ev) => { if (ev.Button == GLMouseEventArgs.MouseButtons.Left) { System.Diagnostics.Debug.WriteLine($"*********************** OPEN"); ctx1.Show(displaycontrol, ev.ScreenCoord); } else if (ev.Button == GLMouseEventArgs.MouseButtons.Right) { ctx2.Show(displaycontrol, ev.ScreenCoord); } }; } } gl3dcontroller = new Controller3D(); gl3dcontroller.ZoomDistance = 5000F; gl3dcontroller.YHoldMovement = true; gl3dcontroller.PaintObjects = Controller3dDraw; gl3dcontroller.KeyboardTravelSpeed = (ms, eyedist) => { return((float)ms * 10.0f); }; gl3dcontroller.MatrixCalc.InPerspectiveMode = true; if (displaycontrol != null) { gl3dcontroller.Start(mc, displaycontrol, new Vector3(0, 0, 10000), new Vector3(140.75f, 0, 0), 0.5F); // HOOK the 3dcontroller to the form so it gets Form events displaycontrol.Paint += (o, ts) => // subscribing after start means we paint over the scene, letting transparency work { displaycontrol.Render(glwfc.RenderState, ts); // we use the same matrix calc as done in controller 3d draw }; } else { gl3dcontroller.Start(glwfc, new Vector3(0, 0, 10000), new Vector3(140.75f, 0, 0), 0.5F); // HOOK the 3dcontroller to the form so it gets Form events } systemtimer.Interval = 25; systemtimer.Tick += new EventHandler(SystemTick); systemtimer.Start(); }
// 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 = 100F; 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); }; IGLTexture array2d = items.Add(new GLTexture2DArray(new Bitmap[] { Properties.Resources.mipmap, Properties.Resources.mipmap2, Properties.Resources.mipmap3, Properties.Resources.mipmap4 }, SizedInternalFormat.Rgba8, 9), "2DArray2"); if (true) { items.Add(new GLMultipleTexturedBlended(false, 2), "ShaderPos"); items.Shader("ShaderPos").StartAction += (s, m) => { array2d.Bind(1); }; Vector4[] instancepositions = new Vector4[4]; instancepositions[0] = new Vector4(-25, 0, -40, 0); // last is image index.. instancepositions[1] = new Vector4(-25, 0, 0, 0); instancepositions[2] = new Vector4(-25, 0, 40, 2); instancepositions[3] = new Vector4(-25, 0, 80, 2); GLRenderState rt = GLRenderState.Tri(cullface: false); rObjects.Add(items.Shader("ShaderPos"), GLRenderableItem.CreateVector4Vector2Vector4(items, PrimitiveType.Triangles, rt, GLSphereObjectFactory.CreateTexturedSphereFromTriangles(3, 20.0f), instancepositions, ic: 4, separbuf: true )); } // Shader MAT if (true) { IGLProgramShader smat = items.Add(new GLMultipleTexturedBlended(true, 2), "ShaderMat"); smat.StartAction += (s, m) => { array2d.Bind(1); }; Matrix4[] pos2 = new Matrix4[3]; pos2[0] = Matrix4.CreateRotationY(-80f.Radians()); pos2[0] *= Matrix4.CreateTranslation(new Vector3(25, 0, -40)); pos2[0].M44 = 0; // this is the image number pos2[1] = Matrix4.CreateRotationY(-70f.Radians()); pos2[1] *= Matrix4.CreateTranslation(new Vector3(25, 0, 0)); pos2[1].M44 = 2; // this is the image number pos2[2] = Matrix4.CreateRotationZ(-60f.Radians()); pos2[2] *= Matrix4.CreateTranslation(new Vector3(25, 0, 40)); pos2[2].M44 = 0; // this is the image number GLRenderState rq = GLRenderState.Quads(cullface: false); rObjects.Add(items.Shader("ShaderMat"), GLRenderableItem.CreateVector4Vector2Matrix4(items, PrimitiveType.Quads, rq, GLShapeObjectFactory.CreateQuad(20.0f, 20.0f, new Vector3(-90f.Radians(), 0, 0)), GLShapeObjectFactory.TexQuadCW, pos2, ic: 3, separbuf: false )); } items.Add(new GLMatrixCalcUniformBlock(), "MCUB"); // def binding of 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); gl3dcontroller.KeyboardTravelSpeed = (ms, eyedist) => { return((float)ms / 100.0f); }; items.Add(new GLColorShaderWorld(), "COSW"); var vs = new GLPLVertexShaderColorModelObjectTranslation(new string[] { "modelpos" }, TransformFeedbackMode.InterleavedAttribs); var fs = new GLPLFragmentShaderVSColor(); var cosot = new GLShaderPipeline(vs, fs); items.Add(cosot, "COSOT"); ts1 = new GLOperationQueryTimeStamp(); ts2 = new GLOperationQueryTimeStamp(); rObjects.Add(ts1); #region coloured lines GLRenderState def = new GLRenderState() { DepthTest = true }; // set up default state for fixed values - no depth test, rely on stencil sync = new GLOperationFenceSync(); #region Coloured triangles if (true) { GLRenderState rc = GLRenderState.Tri(def); rc.CullFace = true; var shape = GLCubeObjectFactory.CreateSolidCubeFromTriangles(5f); rObjects.Add(cosot, "Tri1", GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Triangles, rc, shape, new Color4[] { Color4.Red, Color4.Red, Color4.Red, Color4.Red, Color4.Yellow, Color4.Yellow }, new GLRenderDataTranslationRotation(new Vector3(10, 3, 20)) )); } for (int i = 0; i < 1000; i++) { GLRenderState lines = GLRenderState.Lines(def, 5); 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.White, Color.Red, Color.DarkRed, Color.DarkRed }) ); GLRenderState lines2 = GLRenderState.Lines(def, 1); rObjects.Add(items.Shader("COSW"), GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Lines, lines2, GLShapeObjectFactory.CreateLines(new Vector3(-100, -0, -100), new Vector3(100, -0, -100), new Vector3(0, 0, 10), 21), new Color4[] { Color.Orange, Color.Blue, Color.DarkRed, Color.DarkRed })); rObjects.Add(items.Shader("COSW"), GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Lines, lines2, GLShapeObjectFactory.CreateLines(new Vector3(-100, 10, -100), new Vector3(-100, 10, 100), new Vector3(10, 0, 0), 21), new Color4[] { Color.Yellow, Color.Orange, Color.Yellow, Color.Orange }) ); rObjects.Add(items.Shader("COSW"), GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Lines, lines2, GLShapeObjectFactory.CreateLines(new Vector3(-100, 10, -100), new Vector3(100, 10, -100), new Vector3(0, 0, 10), 21), new Color4[] { Color.Yellow, Color.Orange, Color.Yellow, Color.Orange }) ); } rObjects.Add(sync); rObjects.Add(ts2); #endregion #endregion #region Matrix Calc Uniform items.Add(new GLMatrixCalcUniformBlock(), "MCUB"); // def binding of 0 #endregion }
protected override void OnLoad(EventArgs e) { base.OnLoad(e); Closed += ShaderTest_Closed; matrixcalc = new GLMatrixCalc(); matrixcalc.PerspectiveNearZDistance = 1f; matrixcalc.PerspectiveFarZDistance = worldsize * 2; matrixcalc.InPerspectiveMode = true; matrixcalc.ResizeViewPort(this, glwfc.Size); displaycontrol = new GLControlDisplay(items, glwfc, matrixcalc); // hook form to the window - its the master, it takes its size fro mc.ScreenCoordMax displaycontrol.Focusable = true; // we want to be able to focus and receive key presses. displaycontrol.Name = "displaycontrol"; 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 displaycontrol.Render(glwfc.RenderState, ts); }; double startspeed = 60 * 60 * 6; // in sec GLImage minus = new GLImage("plus", new Rectangle(0, 0, 32, 32), Properties.Resources.GoBackward); minus.MouseClick += (e1, m1) => { currentjd -= 365; }; displaycontrol.Add(minus); GLImage back = new GLImage("back", new Rectangle(40, 0, 32, 32), Properties.Resources.Backwards); back.MouseClick += (e1, m1) => { if (jdscaling > 0) { jdscaling /= 2; } else if (jdscaling < 0) { jdscaling *= 2; } else { jdscaling = -startspeed; } }; displaycontrol.Add(back); GLImage pause = new GLImage("back", new Rectangle(80, 0, 32, 32), Properties.Resources.Pause); pause.MouseClick += (e1, m1) => { jdscaling = 0; }; displaycontrol.Add(pause); GLImage fwd = new GLImage("fwd", new Rectangle(120, 0, 32, 32), Properties.Resources.Forward); fwd.MouseClick += (e1, m1) => { if (jdscaling < 0) { jdscaling /= 2; } else if (jdscaling > 0) { jdscaling *= 2; } else { jdscaling = startspeed; } }; displaycontrol.Add(fwd); GLImage plus = new GLImage("plus", new Rectangle(160, 0, 32, 32), Properties.Resources.GoForward); plus.MouseClick += (e1, m1) => { currentjd += 365; }; displaycontrol.Add(plus); status = new GLLabel("state", new Rectangle(200, 0, 400, 20), "Label", Color.DarkOrange); displaycontrol.Add(status); datalabel = new GLLabel("datalabel", new Rectangle(0, 40, 400, 100), "", Color.DarkOrange); datalabel.TextAlign = ContentAlignment.TopLeft; displaycontrol.Add(datalabel); gl3dcontroller = new Controller3D(); gl3dcontroller.PaintObjects = ControllerDraw; gl3dcontroller.ZoomDistance = 3000F; gl3dcontroller.Start(matrixcalc, displaycontrol, new Vector3(0, 0, 0), new Vector3(135f, 0, 0f), 0.025F); gl3dcontroller.KeyboardTravelSpeed = (ms, eyedist) => { return((float)ms * 100.0f); }; items.Add(new GLColorShaderWorld(), "COSW"); items.Add(new GLTexturedShaderObjectCommonTranslation(), "TEXOCT"); items.Add(new GLTexture2D(Properties.Resources.golden, SizedInternalFormat.Rgba8), "golden"); items.Add(new GLTexture2D(Properties.Resources.moonmap1k, SizedInternalFormat.Rgba8), "moon"); #region coloured lines int gridsize = (int)(worldsize * mscaling); int markers = gridsize / 20; { GLRenderState lines = GLRenderState.Lines(1); Color gridcolour = Color.FromArgb(255, 60, 60, 60); rObjects.Add(items.Shader("COSW"), GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Lines, lines, GLShapeObjectFactory.CreateLines(new Vector3(-gridsize, -0, -gridsize), new Vector3(-gridsize, -0, gridsize), new Vector3(markers, 0, 0), gridsize / markers * 2 + 1), new Color4[] { gridcolour }) ); rObjects.Add(items.Shader("COSW"), GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Lines, lines, GLShapeObjectFactory.CreateLines(new Vector3(-gridsize, -0, -gridsize), new Vector3(gridsize, -0, -gridsize), new Vector3(0, 0, markers), gridsize / markers * 2 + 1), new Color4[] { gridcolour })); } rObjects.Add(new GLOperationClearDepthBuffer()); { GLRenderState rt = GLRenderState.Tri(); float sunscaled = sunradiusm * mscaling * sunscaleup; rObjects.Add(items.Shader("TEXOCT"), "sun", GLRenderableItem.CreateVector4Vector2(items, PrimitiveType.Triangles, rt, GLSphereObjectFactory.CreateTexturedSphereFromTriangles(3, sunscaled), new GLRenderDataTranslationRotationTexture(items.Tex("golden"), new Vector3(0, 0, 0)) )); } #endregion { // debug check DateTime t = new DateTime(2000, 1, 1, 12, 0, 0); double jd = t.ToJulianDate(); DateTime t2 = jd.JulianToDateTime(); System.Diagnostics.Debug.WriteLine($"Date time {t} JD {jd} back to {t2}"); } items.Add(new GLMatrixCalcUniformBlock(), "MCUB"); // create a matrix uniform block currentjd = KeplerOrbitElements.J2000; jdscaling = 0; bodies = new KeplerOrbitElements[4]; bodypositions = new GLRenderDataTranslationRotationTexture[4]; // earth bodies[0] = new KeplerOrbitElements(true, semimajoraxiskm: 0.38709893 * AU, // https://nssdc.gsfc.nasa.gov/planetary/factsheet/mercuryfact.html eccentricity: 0.20563069, inclination: 7.00487, longitudeofascendingnode: 48.33167, longitudeofperihelion: 77.45645, meanlongitude: 252.25084, currentjd); bodies[1] = new KeplerOrbitElements(true, semimajoraxiskm: 0.72333199 * AU, // https://nssdc.gsfc.nasa.gov/planetary/factsheet/venusfact.html eccentricity: 0.00677323, inclination: 3.39471, longitudeofascendingnode: 76.68069, longitudeofperihelion: 131.53298, meanlongitude: 181.97973, currentjd); bodies[2] = new KeplerOrbitElements(true, semimajoraxiskm: 1.49596E+08, // https://nssdc.gsfc.nasa.gov/planetary/factsheet/earthfact.html eccentricity: 0.0167086, inclination: 0.00005, longitudeofascendingnode: -11.26064, longitudeofperihelion: 102.94719, meanlongitude: 100.46435, currentjd); bodies[3] = new KeplerOrbitElements(true, semimajoraxiskm: 1.52366231 * AU, // https://nssdc.gsfc.nasa.gov/planetary/factsheet/marsfact.html eccentricity: 0.09341233, inclination: 1.85061, longitudeofascendingnode: 49.57854, longitudeofperihelion: 336.04084, meanlongitude: 355.45332, currentjd); float planetsize = earthradiusm * mscaling * planetscaleup; for (int i = 0; i < bodies.Length; i++) { bodies[i].CentralMass = Msol; System.Diagnostics.Debug.WriteLine($"{i} {bodies[i].OrbitalPeriodS/60/60/24} {bodies[i].CalculateMass(bodies[i].OrbitalPeriodS)}"); bodypositions[i] = new GLRenderDataTranslationRotationTexture(items.Tex("moon"), new Vector3(0, 0, 0)); GLRenderState rt = GLRenderState.Tri(); rObjects.Add(items.Shader("TEXOCT"), "Body" + i, GLRenderableItem.CreateVector4Vector2(items, PrimitiveType.Triangles, rt, GLSphereObjectFactory.CreateTexturedSphereFromTriangles(3, planetsize), bodypositions[i])); Vector4[] orbit = bodies[i].Orbit(currentjd, 1, mscaling); GLRenderState lines = GLRenderState.Lines(1); rObjects.Add(items.Shader("COSW"), GLRenderableItem.CreateVector4Color4(items, PrimitiveType.LineStrip, lines, orbit, new Color4[] { Color.FromArgb(255, 128, 0, 0) })); } systemtimer.Interval = 25; systemtimer.Tick += new EventHandler(SystemTick); systemtimer.Start(); }
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)); } }
public void Start(GLWinFormControl glwfc) { this.glwfc = glwfc; matrixcalc = new GLMatrixCalc(); matrixcalc.PerspectiveNearZDistance = 1f; matrixcalc.PerspectiveFarZDistance = worldsize * 2; matrixcalc.InPerspectiveMode = true; matrixcalc.ResizeViewPort(this, glwfc.Size); items.Add(new GLMatrixCalcUniformBlock(), "MCUB"); // create a matrix uniform block displaycontrol = new GLControlDisplay(items, glwfc, matrixcalc); // hook form to the window - its the master, it takes its size from mc.ScreenCoordMax displaycontrol.Focusable = true; // we want to be able to focus and receive key presses. displaycontrol.Name = "displaycontrol"; displaycontrol.Font = new Font("Arial", 12); gl3dcontroller = new Controller3Dd(); gl3dcontroller.PaintObjects = ControllerDraw; gl3dcontroller.ZoomDistance = 20e6 * 1000 * mscaling; // zoom 1 is X km gl3dcontroller.PosCamera.ZoomMin = 0.001f; gl3dcontroller.PosCamera.ZoomMax = 300f; gl3dcontroller.PosCamera.ZoomScaling = 1.08f; gl3dcontroller.Start(matrixcalc, displaycontrol, new Vector3d(0, 0, 0), new Vector3d(135f, 0, 0f), 0.025F, registermouseui: false, registerkeyui: true); 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); }; for (int i = 1; i <= 10; i++) { int v = i * i; double f = (gl3dcontroller.PosCamera.ZoomMax - gl3dcontroller.PosCamera.ZoomMin) * v / 100.0 + gl3dcontroller.PosCamera.ZoomMin; System.Diagnostics.Debug.WriteLine($"{i} {v} {f}"); } displaycontrol.Paint += (o, ts) => // subscribing after Controller start means we paint over the scene { // MCUB set up by Controller3DDraw which did the work first // System.Diagnostics.Debug.WriteLine("Controls Draw"); displaycontrol.Render(glwfc.RenderState, ts); }; displaycontrol.MouseClick += MouseClickOnMap; // grab mouse UI displaycontrol.MouseUp += MouseUpOnMap; displaycontrol.MouseDown += MouseDownOnMap; displaycontrol.MouseMove += MouseMoveOnMap; displaycontrol.MouseWheel += MouseWheelOnMap; double startspeed = 60 * 60 * 6; // in sec GLImage minus = new GLImage("timeplus1y", new Rectangle(0, 0, 32, 32), Properties.Resources.GoBackward); minus.MouseClick += (e1, m1) => { currentjd -= 365; }; displaycontrol.Add(minus); GLImage back = new GLImage("timeback", new Rectangle(40, 0, 32, 32), Properties.Resources.Backwards); back.MouseClick += (e1, m1) => { if (jdscaling > 0) { jdscaling /= 2; } else if (jdscaling < 0) { jdscaling *= 2; } else { jdscaling = -startspeed; } }; displaycontrol.Add(back); GLImage pause = new GLImage("timepause", new Rectangle(80, 0, 32, 32), Properties.Resources.Pause); pause.MouseClick += (e1, m1) => { jdscaling = 0; }; displaycontrol.Add(pause); GLImage fwd = new GLImage("timefwd", new Rectangle(120, 0, 32, 32), Properties.Resources.Forward); fwd.MouseClick += (e1, m1) => { if (jdscaling < 0) { jdscaling /= 2; } else if (jdscaling > 0) { jdscaling *= 2; } else { jdscaling = startspeed; } }; displaycontrol.Add(fwd); GLImage plus = new GLImage("timeplus1y", new Rectangle(160, 0, 32, 32), Properties.Resources.GoForward); plus.MouseClick += (e1, m1) => { currentjd += 365; }; displaycontrol.Add(plus); GLImage sysleft = new GLImage("sysleft", new Rectangle(200, 0, 32, 32), Properties.Resources.GoBackward); sysleft.MouseClick += (e1, m1) => { DisplayNode(-1); }; displaycontrol.Add(sysleft); mastersystem = new GLLabel("sysname", new Rectangle(230, 6, 70, 20), "All", Color.DarkOrange); mastersystem.TextAlign = ContentAlignment.MiddleCenter; displaycontrol.Add(mastersystem); GLImage sysright = new GLImage("sysright", new Rectangle(300, 0, 32, 32), Properties.Resources.GoForward); sysright.MouseClick += (e1, m1) => { DisplayNode(1); }; displaycontrol.Add(sysright); timedisplay = new GLLabel("state", new Rectangle(340, 6, 800, 20), "Label", Color.DarkOrange); displaycontrol.Add(timedisplay); datalabel = new GLLabel("datalabel", new Rectangle(0, 40, 400, 100), "", Color.DarkOrange); datalabel.TextAlign = ContentAlignment.TopLeft; displaycontrol.Add(datalabel); status = new GLLabel("Status", new Rectangle(0, 0, 2000, 24), "x"); status.Dock = DockingType.BottomLeft; status.ForeColor = Color.Orange; status.BackColor = Color.FromArgb(50, 50, 50, 50); displaycontrol.Add(status); rightclickmenubody = new GLContextMenu("RightClickMenuBody", new GLMenuItem("RCMInfo", "Information") { MouseClick = (s, e) => { } }, new GLMenuItem("RCMZoomIn", "Track") { MouseClick = (s, e) => { track = (int)rightclickmenubody.Tag; } }, new GLMenuItem("RCMZoomIn", "Track Central Body") { MouseClick = (s, e) => { int body = (int)rightclickmenubody.Tag; if (bodyinfo[body].parentindex >= 0) { track = bodyinfo[body].parentindex; } } }, new GLMenuItem("RCMZoomIn", "Zoom In") { }, new GLMenuItem("RCMUntrack", "Untrack") { MouseClick = (s1, e1) => { track = -1; } } ); rightclickmenubody.Opening += (ms, tag) => { ms["RCMUntrack"].Enabled = track != -1; }; rightclickmenuscreen = new GLContextMenu("RightClickMenuBody", new GLMenuItem("RCMSysDisplay", "System Display") { MouseClick = (s, e) => { } }, new GLMenuItem("RCMUntrack", "Untrack") { MouseClick = (s1, e1) => { track = -1; } } ); rightclickmenuscreen.Opening += (ms, tag) => { ms["RCMUntrack"].Enabled = track != -1; }; if (true) { var shader = new GLColorShaderWorld(); items.Add(shader); GLRenderState lines = GLRenderState.Lines(1); lines.DepthTest = false; int gridsize = (int)(worldsize * mscaling); int gridoffset = (int)(gridlines * mscaling); int nolines = gridsize / gridoffset * 2 + 1; Color gridcolour = Color.FromArgb(80, 80, 80, 80); rObjects.Add(shader, GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Lines, lines, GLShapeObjectFactory.CreateLines(new Vector3(-gridsize, -0, -gridsize), new Vector3(-gridsize, -0, gridsize), new Vector3(gridoffset, 0, 0), nolines), new Color4[] { gridcolour }) ); rObjects.Add(shader, GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Lines, lines, GLShapeObjectFactory.CreateLines(new Vector3(-gridsize, -0, -gridsize), new Vector3(gridsize, -0, -gridsize), new Vector3(0, 0, gridoffset), nolines), new Color4[] { gridcolour })); Size bmpsize = new Size(128, 30); var maps = new GLBitmaps("bitmap1", rObjects, bmpsize, 3, OpenTK.Graphics.OpenGL4.SizedInternalFormat.Rgba8, false, false); using (StringFormat fmt = new StringFormat(StringFormatFlags.NoWrap) { Alignment = StringAlignment.Near, LineAlignment = StringAlignment.Center }) { float hsize = 40e6f * 1000 * mscaling; // million km -> m -> scaling float vsize = hsize * bmpsize.Height / bmpsize.Width; Font f = new Font("MS sans serif", 12f); long pos = -nolines / 2 * (gridlines / 1000); for (int i = -nolines / 2; i < nolines / 2; i++) { if (i != 0) { double v = Math.Abs(pos * 1000); long p = Math.Abs(pos); maps.Add(i, (p).ToString("N0"), f, Color.White, Color.Transparent, new Vector3(i * gridoffset + hsize / 2, 0, vsize / 2), new Vector3(hsize, 0, 0), new Vector3(0, 0, 0), fmt); maps.Add(i, (v / oneAU_m).ToString("N1") + "AU", f, Color.White, Color.Transparent, new Vector3(i * gridoffset + hsize / 2, 0, -vsize / 2), new Vector3(hsize, 0, 0), new Vector3(0, 0, 0), fmt); maps.Add(i, (p).ToString("N0"), f, Color.White, Color.Transparent, new Vector3(hsize / 2, 0, i * gridoffset + vsize / 2), new Vector3(hsize, 0, 0), new Vector3(0, 0, 0), fmt); maps.Add(i, (v / oneAU_m).ToString("N1") + "AU", f, Color.White, Color.Transparent, new Vector3(hsize / 2, 0, i * gridoffset - vsize / 2), new Vector3(hsize, 0, 0), new Vector3(0, 0, 0), fmt); } pos += 50000000; } } } var orbitlinesvertshader = new GLPLVertexShaderModelWorldUniform(new Color[] { Color.FromArgb(128, 128, 0, 0), Color.FromArgb(128, 128, 128, 0) }); orbitlineshader = new GLShaderPipeline(orbitlinesvertshader, new GLPLFragmentShaderVSColor()); bodyplaneshader = new GLShaderPipeline(orbitlinesvertshader, new GLPLFragmentShaderVSColor()); // model pos in, with uniform world pos, vectors out, with vs_colour selected by worldpos.w // set up ARB IDs for all images we are going to use.. var tbs = items.NewBindlessTextureHandleBlock(arbblock); var texs = items.NewTexture2D(null, Properties.Resources.golden, SizedInternalFormat.Rgba8); var texp = items.NewTexture2D(null, Properties.Resources.moonmap1k, SizedInternalFormat.Rgba8); var texb = items.NewTexture2D(null, Properties.Resources.dotted, SizedInternalFormat.Rgba8); var texs2 = items.NewTexture2D(null, Properties.Resources.wooden, SizedInternalFormat.Rgba8); tbs.WriteHandles(new IGLTexture[] { texs, texp, texb, texs2 }); // using 0 tex coord, 4 image id and arb text binding var bodyfragshader = new GLPLFragmentShaderBindlessTexture(arbblock, discardiftransparent: true, useprimidover2: false); // takes 0:Vector4 model, 1: vec2 text, 4:matrix, out is 0:tex, 1: modelpos, 2: instance, 4 = matrix[3][3] var bodyvertshader = new GLPLVertexShaderModelMatrixTexture(1000000 * 1000 * mscaling, useeyedistance: false); bodyshader = new GLShaderPipeline(bodyvertshader, bodyfragshader); items.Add(bodyshader); // hold shape var sphereshape = GLSphereObjectFactory.CreateTexturedSphereFromTriangles(3, 1.0f); spherebuffer = items.NewBuffer(); // fill buffer with model co-ords spherebuffer.AllocateFill(sphereshape.Item1); spheretexcobuffer = items.NewBuffer(); // fill buffer with tex coords spheretexcobuffer.AllocateFill(sphereshape.Item2); bodymatrixbuffer = items.NewBuffer(); // this holds the matrix to set position and size GLStorageBlock findbufferresults = items.NewStorageBlock(findblock); var geofind = new GLPLGeoShaderFindTriangles(findbufferresults, 16); // pass thru normal vert/tcs/tes then to geoshader for results findshader = items.NewShaderPipeline(null, bodyvertshader, null, null, geofind, null, null, null); }
private void CreateBodies(StarScan.ScanNode node, int subnode) { rBodyObjects.Clear(); bodyinfo = new List <BodyInfo>(); bool sysenabled = false; if (subnode > 0 && node.NodeType == StarScan.ScanNodeType.barycentre && node.Children != null) { node = node.Children.Values[subnode - 1]; sysenabled = true; } displaycontrol.ApplyToControlOfName("sys*", (c) => { c.Visible = sysenabled; }); BodyInfo.CreateInfoTree(node, null, -1, 0, bodyinfo); foreach (var o in bodyinfo) { System.Diagnostics.Debug.Write($"Body {o.scannode.OwnName} {o.scannode.scandata?.StarType} {o.scannode.scandata?.PlanetClass} Lvl {o.scannode.Level} "); if (o.kepler != null) { System.Diagnostics.Debug.Write($"SMA {o.kepler.SemiMajorAxis / oneAU_m} AU {o.kepler.SemiMajorAxis / 1000} km " + $" Ecc {o.kepler.Eccentricity} Orbital Period {o.kepler.OrbitalPeriodS / 24 / 60 / 60 / 365} Y Radius {o.scannode.scandata.nRadius} m CM {o.kepler.CentralMass} axt {o.scannode.scandata.nAxialTilt}"); } System.Diagnostics.Debug.WriteLine(""); if (o.kepler != null) { Vector4[] orbit = o.kepler.Orbit(currentjd, 0.1, mscaling); GLRenderState lines = GLRenderState.Lines(1); lines.DepthTest = false; o.orbitpos.ColorIndex = node.scandata?.nRadius != null ? 0 : 1; var riol = GLRenderableItem.CreateVector4(items, PrimitiveType.LineStrip, lines, orbit, o.orbitpos); rBodyObjects.Add(orbitlineshader, riol); GLRenderState quad = GLRenderState.Quads(cullface: false); quad.DepthTest = false; var s = 100000e3f * mscaling; var quadpos = new Vector4[] { new Vector4(-s, 0, -s, 1), new Vector4(-s, 0, +s, 1), new Vector4(+s, 0, +s, 1), new Vector4(+s, 0, -s, 1) }; var plane = GLRenderableItem.CreateVector4(items, PrimitiveType.Quads, quad, quadpos, o.bodypos); rBodyObjects.Add(bodyplaneshader, plane); } } int bodies = bodyinfo.Count; // hold planet and barycentre positions/sizes/imageno bodymatrixbuffer.AllocateBytes(GLBuffer.Mat4size * bodies); GLRenderState rt = GLRenderState.Tri(); rt.DepthTest = false; var ribody = GLRenderableItem.CreateVector4Vector2Matrix4(items, PrimitiveType.Triangles, rt, spherebuffer, spheretexcobuffer, bodymatrixbuffer, spherebuffer.Length / sizeof(float) / 4, ic: bodies, matrixdivisor: 1); rBodyObjects.Add(bodyshader, ribody); rifind = GLRenderableItem.CreateVector4Vector2Matrix4(items, PrimitiveType.Triangles, GLRenderState.Tri(), spherebuffer, spheretexcobuffer, bodymatrixbuffer, spherebuffer.Length / sizeof(float) / 4, ic: bodies, matrixdivisor: 1); }
/// <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)); }