/// <summary> /// Add a bitmap to the collection. /// </summary> /// <param name="tag">Tag for this bitmap, may be null</param> /// <param name="bmp">Bitmap</param> /// <param name="bmpmipmaplevels">The bitmap mip map levels</param> /// <param name="worldpos">Position of bitmap in world</param> /// <param name="size">Size to draw bitmap in world.</param> /// <param name="rotationradians">Rotation of bitmap (ignored if rotates below are on)</param> /// <param name="rotatetoviewer">True to rotate to viewer in azimuth</param> /// <param name="rotateelevation">True to rotate to viewer in elevation</param> /// <param name="alphafadescalar">Alpha Fade scalar on distance</param> /// <param name="alphafadepos">Alpha fade distance. Negative for fade in, positive for fade out </param> /// <param name="ownbitmap"></param> /// <param name="visible">True if visible on start</param> /// <returns></returns> // add a bitmap, indicate if owned by class or you. Gives back group no, position in group, total in group public virtual Tuple <int, int, int> Add(object tag, Bitmap bmp, int bmpmipmaplevels, Vector3 worldpos, Vector3 size, Vector3 rotationradians, bool rotatetoviewer = false, bool rotateelevation = false, float alphafadescalar = 0, float alphafadepos = 0, bool ownbitmap = false, bool visible = true ) { System.Diagnostics.Debug.Assert(context == GLStatics.GetContext(), "Bitmaps detected context incorrect"); Matrix4 mat = GLPLVertexShaderMatrixQuadTexture.CreateMatrix(worldpos, size, rotationradians, rotatetoviewer, rotateelevation, alphafadescalar, alphafadepos, 0, visible); var gpc = matrixbuffers.Add(tag, ownbitmap ? bmp : null, mat); // group, pos, total in group // System.Diagnostics.Debug.WriteLine("Make bitmap {0} {1} {2} at {3}", gpc.Item1, gpc.Item2, gpc.Item3 , worldpos); grouptextureslist[gpc.Item1].LoadBitmap(bmp, gpc.Item2, false, bmpmipmaplevels); // texture does not own them, we may do grouprenderlist[gpc.Item1].InstanceCount = gpc.Item3; // update instance count to items in group return(gpc); }
protected override void OnLoad(EventArgs e) { base.OnLoad(e); Closed += ShaderTest_Closed; gl3dcontroller = new Controller3D(); gl3dcontroller.PaintObjects = ControllerDraw; gl3dcontroller.MatrixCalc.PerspectiveNearZDistance = 1f; gl3dcontroller.MatrixCalc.PerspectiveFarZDistance = 1000f; gl3dcontroller.ZoomDistance = 20F; gl3dcontroller.Start(glwfc, new Vector3(0, 0, 0), new Vector3(110f, 0, 0f), 1F); glwfc.MouseClick += GLMouseClick; gl3dcontroller.KeyboardTravelSpeed = (ms, eyedist) => { return((float)ms / 40.0f); }; items.Add(new GLColorShaderWorld(), "COSW"); items.Add(new GLColorShaderObjectTranslation(), "COSOT"); #region coloured lines if (true) { GLRenderState lines = GLRenderState.Lines(1); rObjects.Add(items.Shader("COSW"), GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Lines, lines, GLShapeObjectFactory.CreateLines(new Vector3(-100, -0, -100), new Vector3(-100, -0, 100), new Vector3(10, 0, 0), 21), new Color4[] { Color.Red, Color.Red, Color.DarkRed, Color.DarkRed }) ); rObjects.Add(items.Shader("COSW"), GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Lines, lines, GLShapeObjectFactory.CreateLines(new Vector3(-100, -0, -100), new Vector3(100, -0, -100), new Vector3(0, 0, 10), 21), new Color4[] { Color.Red, Color.Red, Color.DarkRed, Color.DarkRed })); } #endregion #region Coloured triangles if (true) { GLRenderState rc = GLRenderState.Tri(); rc.CullFace = false; rObjects.Add(items.Shader("COSOT"), "scopen", GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Triangles, rc, GLCubeObjectFactory.CreateSolidCubeFromTriangles(5f), new Color4[] { Color4.Red, Color4.Green, Color4.Blue, Color4.White, Color4.Cyan, Color4.Orange }, new GLRenderDataTranslationRotation(new Vector3(10, 0, 20)) )); } #endregion var sunvertex = new GLPLVertexShaderModelCoordWorldAutoscale(new Color[] { Color.FromArgb(255, 220, 220, 10), Color.FromArgb(255, 0, 0, 0) }); items.Add(sunvertex); var sunshader = new GLShaderPipeline(sunvertex, new GLPLStarSurfaceFragmentShader()); items.Add(sunshader); var shapebuf = new GLBuffer(); items.Add(shapebuf); var shape = GLSphereObjectFactory.CreateSphereFromTriangles(1, 0.5f); shapebuf.AllocateFill(shape); GLStorageBlock block = new GLStorageBlock(20); findshader = items.NewShaderPipeline(null, sunvertex, null, null, new GLPLGeoShaderFindTriangles(block, 16), null, null, null); int texunitspergroup = 16; // opengl minimum texture units per frag shader //var textshader = new GLShaderPipeline(new GLPLVertexShaderQuadTextureWithMatrixTranslation(), new GLPLFragmentShaderTexture2DIndexedMulti(0,0,true, texunitspergroup)); var textshader = new TextShader(texunitspergroup); items.Add(textshader); Font fnt = new Font("MS sans serif", 16f); if (true) { int maxstars = 1000; // this is an aspriation, depends on fragmentation of the system dataindirectbuffer = new GLVertexBufferIndirect(items, maxstars * (GLBuffer.Vec4size + GLBuffer.Mat4size), GLBuffer.WriteIndirectArrayStride * 100, true); var textarray = new GLTexture2DArray(128, 32, maxstars, SizedInternalFormat.Rgba8); int SectorSize = 10; { Vector3 pos = new Vector3(-20, 0, -15); Vector4[] array = new Vector4[10]; Random rnd = new Random(23); for (int i = 0; i < array.Length; i++) { array[i] = new Vector4(pos.X + rnd.Next(SectorSize), pos.Y + rnd.Next(SectorSize), pos.Z + rnd.Next(SectorSize), 0); } dataindirectbuffer.Fill(array, 0, array.Length, 0, shape.Length, 0, array.Length, -1); Matrix4[] matrix = new Matrix4[array.Length]; for (int i = 0; i < array.Length; i++) { int imgpos = textarray.DepthIndex; textarray.DrawText("A" + i, fnt, Color.White, Color.Blue, -1); var mat = GLPLVertexShaderMatrixQuadTexture.CreateMatrix(new Vector3(array[i].X, array[i].Y + 0.6f, array[i].Z), new Vector3(1, 0, 0.2f), new Vector3(-90F.Radians(), 0, 0), imagepos: imgpos); matrix[i] = mat; } dataindirectbuffer.Vertex.AlignMat4(); // instancing counts in mat4 sizes (mat4 0 @0, mat4 1 @ 64 etc) so align to it dataindirectbuffer.Fill(matrix, 0, matrix.Length, 1, 4, 0, array.Length, -1); } if (true) { Vector3 pos = new Vector3(-20, 0, 0); Vector4[] array = new Vector4[5]; Random rnd = new Random(23); for (int i = 0; i < array.Length; i++) { array[i] = new Vector4(pos.X + rnd.Next(SectorSize), pos.Y + rnd.Next(SectorSize), pos.Z + rnd.Next(SectorSize), 0); } dataindirectbuffer.Fill(array, 0, array.Length, 0, shape.Length, 0, array.Length, -1); } if (true) { Vector3 pos = new Vector3(-20, 0, 15); Vector4[] array = new Vector4[10]; Random rnd = new Random(23); for (int i = 0; i < array.Length; i++) { array[i] = new Vector4(pos.X + rnd.Next(SectorSize), pos.Y + rnd.Next(SectorSize), pos.Z + rnd.Next(SectorSize), 0); } dataindirectbuffer.Fill(array, 0, array.Length, 0, shape.Length, 0, array.Length, -1); Matrix4[] matrix = new Matrix4[array.Length]; for (int i = 0; i < array.Length; i++) { int imgpos = textarray.DepthIndex; textarray.DrawText("C" + i, fnt, Color.White, Color.Red, -1); var mat = GLPLVertexShaderMatrixQuadTexture.CreateMatrix(new Vector3(array[i].X, array[i].Y + 0.6f, array[i].Z), new Vector3(1, 0, 0.2f), new Vector3(-90F.Radians(), 0, 0), imagepos: imgpos); matrix[i] = mat; } dataindirectbuffer.Vertex.AlignMat4(); // instancing countis in mat4 sizes (mat4 0 @0, mat4 1 @ 64 etc) so align to it dataindirectbuffer.Fill(matrix, 0, matrix.Length, 1, 4, 0, array.Length, -1); } int[] indirectints0 = dataindirectbuffer.Indirects[0].ReadInts(0, 12); int[] indirectints1 = dataindirectbuffer.Indirects[1].ReadInts(0, 4); float[] worldpos = dataindirectbuffer.Vertex.ReadFloats(0, 3 * 2 * 4); if (true) { GLRenderState rt = GLRenderState.Tri(); // render is triangles, with no depth test so we always appear rt.DepthTest = true; rt.DepthClamp = true; var renderer = GLRenderableItem.CreateVector4Vector4(items, PrimitiveType.Triangles, rt, shapebuf, 0, 0, // binding 0 is shapebuf, offset 0, no draw count dataindirectbuffer.Vertex, 0, // binding 1 is vertex's world positions, offset 0 null, 0, 1); // no ic, second divisor 1 renderer.IndirectBuffer = dataindirectbuffer.Indirects[0]; renderer.BaseIndexOffset = 0; // offset in bytes where commands are stored renderer.DrawCount = 3; renderer.MultiDrawCountStride = GLBuffer.WriteIndirectArrayStride; rObjects.Add(sunshader, "sunshader", renderer); } if (true) { var rc = GLRenderState.Quads(); rc.CullFace = true; rc.DepthTest = true; rc.ClipDistanceEnable = 1; // we are going to cull primitives which are deleted var renderer = GLRenderableItem.CreateMatrix4(items, PrimitiveType.Quads, rc, dataindirectbuffer.Vertex, 0, 0, //attach buffer with matrices, no draw count new GLRenderDataTexture(textarray, 0), 0, 1); //no ic, and matrix divide so 1 matrix per vertex set renderer.IndirectBuffer = dataindirectbuffer.Indirects[1]; renderer.BaseIndexOffset = 0; // offset in bytes where commands are stored renderer.DrawCount = 2; renderer.MultiDrawCountStride = GLBuffer.WriteIndirectArrayStride; rObjects.Add(textshader, "textshader", renderer); } } if (true) { GLRenderState starrc = GLRenderState.Tri(); // render is triangles, with no depth test so we always appear starrc.DepthTest = true; starrc.DepthClamp = true; var textrc = GLRenderState.Quads(); textrc.DepthTest = true; textrc.ClipDistanceEnable = 1; // we are going to cull primitives which are deleted sl = new GLObjectsWithLabels(); var ris = sl.Create(texunitspergroup, 50, 50, shapebuf, shape.Length, starrc, PrimitiveType.Triangles, new Size(128, 32), textrc, SizedInternalFormat.Rgba8, 3); rObjects.Add(sunshader, "SLsunshade", ris.Item1); rObjects.Add(textshader, "SLtextshade", ris.Item2); items.Add(sl); int SectorSize = 10; { Vector3 pos = new Vector3(0, 0, -15); Vector4[] array = new Vector4[10]; string[] text = new string[array.Length]; Random rnd = new Random(31); for (int i = 0; i < array.Length; i++) { array[i] = new Vector4(pos.X + rnd.Next(SectorSize), pos.Y + rnd.Next(SectorSize), pos.Z + rnd.Next(SectorSize), 0); text[i] = "A.r" + i; } var mats = GLPLVertexShaderMatrixQuadTexture.CreateMatrices(array, new Vector3(0, 0.6f, 0), new Vector3(2f, 0, 0.4f), new Vector3(-90F.Radians(), 0, 0), true, false); var bmps = GLOFC.Utils.BitMapHelpers.DrawTextIntoFixedSizeBitmaps(sl.LabelSize, text, fnt, System.Drawing.Text.TextRenderingHint.ClearTypeGridFit, Color.White, Color.DarkBlue, 0.5f); List <GLObjectsWithLabels.BlockRef> bref = new List <GLObjectsWithLabels.BlockRef>(); sl.Add(array, mats, bmps, bref); GLOFC.Utils.BitMapHelpers.Dispose(bmps); } { Vector3 pos = new Vector3(0, 0, 0); Vector4[] array = new Vector4[20]; string[] text = new string[array.Length]; Random rnd = new Random(31); for (int i = 0; i < array.Length; i++) { array[i] = new Vector4(pos.X + rnd.Next(SectorSize), pos.Y + rnd.Next(SectorSize), pos.Z + rnd.Next(SectorSize), 0); text[i] = "B." + i; } List <GLObjectsWithLabels.BlockRef> bref = new List <GLObjectsWithLabels.BlockRef>(); sl.Add(array, text, fnt, Color.White, Color.DarkBlue, new Vector3(2f, 0, 0.4f), new Vector3(-90F.Radians(), 0, 0), true, false, null, 0.5f, new Vector3(0, 0.6f, 0), bref); } { Vector3 pos = new Vector3(0, 0, 15); Vector4[] array = new Vector4[10]; string[] text = new string[array.Length]; Random rnd = new Random(31); for (int i = 0; i < array.Length; i++) { array[i] = new Vector4(pos.X + rnd.Next(SectorSize), pos.Y + rnd.Next(SectorSize), pos.Z + rnd.Next(SectorSize), 0); text[i] = "C." + i; } List <GLObjectsWithLabels.BlockRef> bref = new List <GLObjectsWithLabels.BlockRef>(); sl.Add(array, text, fnt, Color.White, Color.DarkBlue, new Vector3(2f, 0, 0.4f), new Vector3(-90F.Radians(), 0, 0), true, false, null, 0.5f, new Vector3(0, 0.6f, 0), bref); } System.Diagnostics.Debug.WriteLine($"Sets {sl.Blocks} Removed {sl.BlocksRemoved}"); } // Sets of.. if (true) { GLRenderState starrc = GLRenderState.Tri(); // render is triangles, with no depth test so we always appear starrc.DepthTest = true; starrc.DepthClamp = true; var textrc = GLRenderState.Quads(); textrc.DepthTest = true; textrc.ClipDistanceEnable = 1; // we are going to cull primitives which are deleted slset = new GLSetOfObjectsWithLabels("SLSet", rObjects, true ? 4 : texunitspergroup, 50, 10, sunshader, shapebuf, shape.Length, starrc, PrimitiveType.Triangles, textshader, new Size(128, 32), textrc, SizedInternalFormat.Rgba8, 3); items.Add(slset); int SectorSize = 10; { Vector3 pos = new Vector3(20, 0, -15); Vector4[] array = new Vector4[10]; string[] text = new string[array.Length]; Random rnd = new Random(31); for (int i = 0; i < array.Length; i++) { array[i] = new Vector4(pos.X + rnd.Next(SectorSize), pos.Y + rnd.Next(SectorSize), pos.Z + rnd.Next(SectorSize), 0); text[i] = "S.A.r" + i; } var mats = GLPLVertexShaderMatrixQuadTexture.CreateMatrices(array, new Vector3(0, 0.6f, 0), new Vector3(2f, 0, 0.4f), new Vector3(-90F.Radians(), 0, 0), true, false); var bmps = GLOFC.Utils.BitMapHelpers.DrawTextIntoFixedSizeBitmaps(slset.LabelSize, text, fnt, System.Drawing.Text.TextRenderingHint.ClearTypeGridFit, Color.White, Color.DarkBlue, 0.5f); slset.Add("GA", text, array, mats, bmps); GLOFC.Utils.BitMapHelpers.Dispose(bmps); } { Vector3 pos = new Vector3(20, 0, 0); Vector4[] array = new Vector4[10]; string[] text = new string[array.Length]; Random rnd = new Random(31); for (int i = 0; i < array.Length; i++) { array[i] = new Vector4(pos.X + rnd.Next(SectorSize), pos.Y + rnd.Next(SectorSize), pos.Z + rnd.Next(SectorSize), 0); text[i] = "S.B." + i; } var mats = GLPLVertexShaderMatrixQuadTexture.CreateMatrices(array, new Vector3(0, 0.6f, 0), new Vector3(2f, 0, 0.4f), new Vector3(-90F.Radians(), 0, 0), true, false); var bmps = GLOFC.Utils.BitMapHelpers.DrawTextIntoFixedSizeBitmaps(slset.LabelSize, text, fnt, System.Drawing.Text.TextRenderingHint.ClearTypeGridFit, Color.White, Color.DarkBlue, 0.5f); slset.Add("GB", text, array, mats, bmps); GLOFC.Utils.BitMapHelpers.Dispose(bmps); } { Vector3 pos = new Vector3(20, 0, 15); Vector4[] array = new Vector4[10]; string[] text = new string[array.Length]; Random rnd = new Random(31); for (int i = 0; i < array.Length; i++) { array[i] = new Vector4(pos.X + rnd.Next(SectorSize), pos.Y + rnd.Next(SectorSize), pos.Z + rnd.Next(SectorSize), 0); text[i] = "S.C." + i; } var mats = GLPLVertexShaderMatrixQuadTexture.CreateMatrices(array, new Vector3(0, 0.6f, 0), new Vector3(2f, 0, 0.4f), new Vector3(-90F.Radians(), 0, 0), true, false); var bmps = GLOFC.Utils.BitMapHelpers.DrawTextIntoFixedSizeBitmaps(slset.LabelSize, text, fnt, System.Drawing.Text.TextRenderingHint.ClearTypeGridFit, Color.White, Color.DarkBlue, 0.5f); slset.Add("GC", text, array, mats, bmps); GLOFC.Utils.BitMapHelpers.Dispose(bmps); } } #region Matrix Calc Uniform items.Add(new GLMatrixCalcUniformBlock(), "MCUB"); // def binding of 0 #endregion }