private void ControllerDraw(Controller3D mc, ulong unused) { System.Diagnostics.Debug.WriteLine("Draw"); GLMatrixCalcUniformBlock mcub = (GLMatrixCalcUniformBlock)items.UB("MCUB"); mcub.SetFull(gl3dcontroller.MatrixCalc); rObjects.Render(glwfc.RenderState, gl3dcontroller.MatrixCalc, true); GLStatics.Check(); GLStatics.Flush(); var t1 = ts1.GetCounter(); var t2 = ts2.GetCounter(); System.Diagnostics.Debug.WriteLine($"Time Taken {t2-t1} ns"); GLMemoryBarrier.All(); Vector3[] values3 = varyingbuffer.ReadVector3sPacked(0, 8); // varyings seem to ignore the vec3->vec4 packed thingy.. System.Diagnostics.Debug.Assert(values3[1] == new Vector3(shape[1].X, shape[1].Y, shape[1].Z)); System.Diagnostics.Debug.Assert(values3[3] == new Vector3(shape[3].X, shape[3].Y, shape[3].Z)); var azel = gl3dcontroller.PosCamera.EyePosition.AzEl(gl3dcontroller.PosCamera.LookAt, true); this.Text = "Looking at " + gl3dcontroller.MatrixCalc.LookAt + " from " + gl3dcontroller.MatrixCalc.EyePosition + " cdir " + gl3dcontroller.PosCamera.CameraDirection + " azel " + azel + " zoom " + gl3dcontroller.PosCamera.ZoomFactor + " dist " + gl3dcontroller.MatrixCalc.EyeDistance + " FOV " + gl3dcontroller.MatrixCalc.FovDeg; }
/// <summary> /// Get results /// </summary> /// <returns>null or vec4 array. Each vec4: PrimitiveID, InstanceID, average Z of triangle points, draw ID | group</returns> public Vector4[] GetResult() { GLMemoryBarrier.All(); vecoutbuffer.StartRead(0); int count = Math.Min(vecoutbuffer.ReadInt(), maximumresults); // atomic counter keeps on going if it exceeds max results, so limit to it Vector4[] d = null; if (count > 0) { d = vecoutbuffer.ReadVector4s(count); // align 16 for vec4 Array.Sort(d, delegate(Vector4 left, Vector4 right) { return(left.Z.CompareTo(right.Z)); }); } vecoutbuffer.StopReadWrite(); return(d); }
private void Controller3DDraw(Controller3D c3d, ulong time) { long t1 = hptimer.ElapsedTicks; //TBD // GL.Finish(); // use GL finish to ensure last frame is done - if we are operating above sys tick rate, this will be small time. If we are rendering too much, it will stall long t2 = hptimer.ElapsedTicks; GLMatrixCalcUniformBlock mcb = ((GLMatrixCalcUniformBlock)items.UB("MCUB")); mcb.SetFull(gl3dcontroller.MatrixCalc); // set the matrix unform block to the controller 3d matrix calc. // set up the grid shader size if (gridrenderable != null) { gridrenderable.InstanceCount = gridvertshader.ComputeGridSize(gl3dcontroller.MatrixCalc.EyeDistance, out lastgridwidth); lasteyedistance = gl3dcontroller.MatrixCalc.EyeDistance; gridvertshader.SetUniforms(gl3dcontroller.MatrixCalc.LookAt, lastgridwidth, gridrenderable.InstanceCount); } if (gridbitmapvertshader != null) { float coordfade = lastgridwidth == 10000 ? (0.7f - (c3d.MatrixCalc.EyeDistance / 20000).Clamp(0.0f, 0.7f)) : 0.7f; Color coordscol = Color.FromArgb(coordfade < 0.05 ? 0 : 150, Color.Cyan); gridbitmapvertshader.ComputeUniforms(lastgridwidth, gl3dcontroller.MatrixCalc, gl3dcontroller.PosCamera.CameraDirection, coordscol, Color.Transparent); } if (edsmgalmapregions != null) { edsmgalmapregions.SetY(gl3dcontroller.PosCamera.LookAt.Y); } if (elitemapregions != null) { elitemapregions.SetY(gl3dcontroller.PosCamera.LookAt.Y); } // set the coords fader // set the galaxy volumetric block if (galaxyrenderable != null) { galaxyrenderable.InstanceCount = volumetricblock.Set(gl3dcontroller.MatrixCalc, volumetricboundingbox, gl3dcontroller.MatrixCalc.InPerspectiveMode ? 50.0f : 0); // set up the volumentric uniform //System.Diagnostics.Debug.WriteLine("GI {0}", galaxyrendererable.InstanceCount); galaxyshader.SetDistance(gl3dcontroller.MatrixCalc.InPerspectiveMode ? c3d.MatrixCalc.EyeDistance : -1f); } long t3 = hptimer.ElapsedTicks; if (travelpath != null) { travelpath.Update(time, gl3dcontroller.MatrixCalc.EyeDistance); } if (galmapobjects != null) { galmapobjects.Update(time, gl3dcontroller.MatrixCalc.EyeDistance); } if (galaxystars != null) { galaxystars.Update(time, gl3dcontroller.MatrixCalc.EyeDistance); } if (galaxystars != null && gl3dcontroller.MatrixCalc.EyeDistance < 400) { galaxystars.Request9BoxConditional(gl3dcontroller.PosCamera.LookAt); } long t4 = hptimer.ElapsedTicks; //int[] queryID = new int[2]; //GL.GenQueries(2, queryID); //GL.QueryCounter(queryID[0], QueryCounterTarget.Timestamp); var tmr1 = new GLOperationQueryTimeStamp(); var tmr2 = new GLOperationQueryTimeStamp(); tmr1.Execute(null); rObjects.Render(glwfc.RenderState, gl3dcontroller.MatrixCalc, verbose: false); tmr2.Execute(null); // GL.QueryCounter(queryID[1], QueryCounterTarget.Timestamp); // GL.Flush(); // ensure everything is in the grapghics pipeline //while (tmr2.IsAvailable() == false) // ; long a = tmr1.GetCounter(); long b = tmr2.GetCounter(); //int done = 0; //while (done == 0) //{ // GL.GetQueryObject(queryID[1], GetQueryObjectParam.QueryResultAvailable, out done); //} //GL.GetQueryObject(queryID[0], GetQueryObjectParam.QueryResult, out long a); //GL.GetQueryObject(queryID[1], GetQueryObjectParam.QueryResult, out long b); //System.Diagnostics.Debug.WriteLine($"timer {a} {b} {b-a}" ); long t5 = hptimer.ElapsedTicks; if (debugbuffer != null) { GLMemoryBarrier.All(); Vector4[] debugout = debugbuffer.ReadVector4s(0, 4); System.Diagnostics.Debug.WriteLine("{0},{1},{2},{3}", debugout[0], debugout[1], debugout[2], debugout[3]); } long t = hptimer.ElapsedMilliseconds; long diff = t - lastms; for (int i = frametimes.Length - 1; i > 0; i--) { frametimes[i] = frametimes[i - 1]; } frametimes[0] = diff; lastms = t; double fps = (1000.0 / diff); if (fpsavg <= 1) { fpsavg = fps; } else { fpsavg = (fpsavg * 0.95) + fps * 0.05; } tmr1.Dispose(); tmr2.Dispose(); if (diff > 0) { // System.Diagnostics.Debug.Write($"Frame {hptimer.ElapsedMilliseconds,6} {diff,3} fps {fpsavg:#.0} frames {frametimes[0],3} {frametimes[1],3} {frametimes[2],3} {frametimes[3],3} {frametimes[4],3} {frametimes[5],3} sec {galaxystars.Sectors,3}"); // System.Diagnostics.Debug.WriteLine($" finish {(t2 - t1) * 1000000 / Stopwatch.Frequency,5} t3 {(t3 - t2) * 1000000 / Stopwatch.Frequency,4} t4 {(t4 - t3) * 1000000 / Stopwatch.Frequency,4} render {(t5 - t4) * 1000000 / Stopwatch.Frequency,5} tot {(t5 - t1) * 1000000 / Stopwatch.Frequency,5}"); } // this.Text = "FPS " + fpsavg.ToString("N0") + " Looking at " + gl3dcontroller.MatrixCalc.TargetPosition + " eye@ " + gl3dcontroller.MatrixCalc.EyePosition + " dir " + gl3dcontroller.Pos.CameraDirection + " Dist " + gl3dcontroller.MatrixCalc.EyeDistance + " Zoom " + gl3dcontroller.Pos.ZoomFactor; }
// update vertexes // make a bitmap if the current child size is different to the stored rectangle size // create or update the texture if the texture was never made, or its not the right size // write the bindless texture list if we updated the texture OR we are forced to // update the vertex buffer with positions private void UpdateVertexPositionsTextures(bool forceupdatetextures = false) { System.Diagnostics.Debug.Assert(context == GLStatics.GetContext() && IsCurrent(), "Context incorrect"); if (ControlsZ.Count > 0) // may end up with nothing to draw, in which case, don't update anything { vertexes.AllocateBytes(ControlsZ.Count * sizeof(float) * vertexesperentry * 4); vertexes.StartWrite(0, vertexes.Length); float z = startz; // we place it in clip space at a z near int controlsvisible = 0; List <IGLTexture> tlist = new List <IGLTexture>(); bool changedtlist = forceupdatetextures; foreach (var c in ControlsIZ) // we paint in IZ order, and we set the Z (bigger is more in the back) from a notional X to 0 so the depth test works { if (c.Visible != visible[c]) // if visible list has changed, then we must rewrite the texture binds list as we don't write vertexes for invisibles { visible[c] = c.Visible; changedtlist = true; } if (c.Visible) // must be visible to be added to vlist { //System.Diagnostics.Debug.WriteLine($"Update texture {c.Name} with {c.Opacity}"); float[] a; float w = c.Opacity; if (c.ScaleWindow == null) { a = new float[] { c.Left, c.Top, z, w, c.Left, c.Bottom, z, w, c.Right, c.Top, z, w, c.Right, c.Bottom, z, w, }; } else { float right = c.Left + c.Width * c.ScaleWindow.Value.Width; float bot = c.Top + c.Height * c.ScaleWindow.Value.Height; a = new float[] { c.Left, c.Top, z, w, c.Left, bot, z, w, right, c.Top, z, w, right, bot, z, w }; } vertexes.Write(a); z -= deltaz; controlsvisible++; if (size[c] != c.Size) // if level bitmap changed size, remake bitmap { // System.Diagnostics.Debug.WriteLine($"Displaycontrol {c.Name} windows size is not texture size {size[c]} remake bitmap"); c.MakeLevelBitmap(c.Width, c.Height); size[c] = c.Size; } if (textures[c].Id < 0 || textures[c].Width != c.LevelBitmap.Width || textures[c].Height != c.LevelBitmap.Height) // if layout changed bitmap { // System.Diagnostics.Debug.WriteLine($"Displaycontrol {c.Name} make new texture of {c.Size} {c.LevelBitmap.Size}"); textures[c].CreateOrUpdateTexture(c.Width, c.Height, SizedInternalFormat.Rgba8); // and make a texture, this will dispose of the old one changedtlist = true; } // System.Diagnostics.Debug.WriteLine($"Update tlist for {c.Name} with {c.Opacity}"); tlist.Add(textures[c]); // need to have them in the same order as the client rectangles } else { //System.Diagnostics.Debug.WriteLine($"{c.Name} not visible so not adding"); } } vertexes.StopReadWrite(); GLOFC.GLStatics.Check(); if (changedtlist) // update if anything has changed { // System.Diagnostics.Debug.WriteLine($"Displaycontrol textures changed, write list"); texturebinds.WriteHandles(tlist.ToArray()); // write texture handles to the buffer.. written in iz order GLMemoryBarrier.All(); } ri.DrawCount = (controlsvisible > 0) ? (controlsvisible * 5 - 1) : 0; // 4 vertexes per rectangle, 1 restart } else { ri.DrawCount = 0; // and set count to zero. } RequestRender = true; }
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, 20); gl3dcontroller.Start(glwfc, new Vector3(0, 0, 0), new Vector3(120f, 0, 0f), 1F); gl3dcontroller.KeyboardTravelSpeed = (ms, eyedist) => { return((float)ms / 20.0f); }; // this bit is eye candy just to show its working items.Add(new GLColorShaderWorld(), "COSW"); GLRenderState rl = GLRenderState.Lines(1); rObjects.Add(items.Shader("COSW"), GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Lines, rl, GLShapeObjectFactory.CreateLines(new Vector3(-40, 0, -40), new Vector3(-40, 0, 40), new Vector3(10, 0, 0), 9), new Color4[] { Color.Red, Color.Red, Color.Green, Color.Green }) ); rObjects.Add(items.Shader("COSW"), GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Lines, rl, GLShapeObjectFactory.CreateLines(new Vector3(-40, 0, -40), new Vector3(40, 0, -40), new Vector3(0, 0, 10), 9), new Color4[] { Color.Red, Color.Red, Color.Green, Color.Green }) ); items.Add(new GLTexture2D(Properties.Resources.moonmap1k, SizedInternalFormat.Rgba8), "moon"); items.Add(new GLTexturedShaderObjectTranslation(), "TEX"); items.Add(new GLMatrixCalcUniformBlock(), "MCUB"); // def binding of 0 // Pass vertex data thru a vertex shader which stores into a block vecoutbuffer = new GLStorageBlock(30, true); vecoutbuffer.AllocateBytes(32000, OpenTK.Graphics.OpenGL4.BufferUsageHint.DynamicCopy); // set size of vec buffer ComputeShader csn = new ComputeShader(); csn.Run(); GLMemoryBarrier.All(); // test consistency between row/columns of matrix4 of code and glsl int count = vecoutbuffer.ReadInt(0); System.Diagnostics.Debug.WriteLine("Count is " + count); { float[] mat4 = vecoutbuffer.ReadFloats(16, 16); System.Diagnostics.Debug.WriteLine("Compare mat4 constructor via order of floats:"); for (int i = 0; i < mat4.Length; i++) { System.Diagnostics.Debug.Write(string.Format("{0} = {1}, ", i, mat4[i])); } System.Diagnostics.Debug.WriteLine(""); } { Vector2[] vec2 = vecoutbuffer.ReadVector2s(4, 2); System.Diagnostics.Debug.WriteLine($"Vec2a = inc {vec2[0].X.Degrees()} az {vec2[0].Y.Degrees()}"); } Matrix4[] mat4r = vecoutbuffer.ReadMatrix4s(32, 32); // read all matrixes System.Diagnostics.Debug.WriteLine("Test mat constructor =" + Environment.NewLine + mat4r[0].ToString()); System.Diagnostics.Debug.WriteLine("Row0 is " + mat4r[0].Row0.ToString()); System.Diagnostics.Debug.WriteLine("Should be 20000 = " + mat4r[0][2, 3]); int id = 1; System.Diagnostics.Debug.WriteLine("Identity matrix = " + Environment.NewLine + mat4r[id++].ToString()); { Matrix4 xrotpi4 = Matrix4.CreateRotationX(0.7853f); // demo that Matrix4.Create is the same values as mat4rotatex System.Diagnostics.Debug.WriteLine("Rotate X Pi/4 =" + GLStaticsMatrix4.ApproxEquals(mat4r[id], xrotpi4) + Environment.NewLine + mat4r[id].ToString()); id++; } { Matrix4 yrotpi4 = Matrix4.CreateRotationY(0.7853f); System.Diagnostics.Debug.WriteLine("Rotate Y Pi/4 =" + GLStaticsMatrix4.ApproxEquals(mat4r[id], yrotpi4) + Environment.NewLine + mat4r[id].ToString()); id++; } { Matrix4 zrotpi4 = Matrix4.CreateRotationZ(0.7853f); System.Diagnostics.Debug.WriteLine("Rotate Z Pi/4 =" + GLStaticsMatrix4.ApproxEquals(mat4r[4], zrotpi4) + Environment.NewLine + mat4r[4].ToString()); id++; } { // test: //Matrix4 xrot = Matrix4.CreateRotationX((float)(Math.PI / 2)); //Matrix4 r1 = new Matrix4(0, 0, 0, 0, // 0, 0, 0, 0, // 0, 0, 1, 0, // 0, 0, 0, 1); //r1 = new Matrix4(new Matrix3()) //Matrix4 r2 = r1 * xrot; //System.Diagnostics.Debug.WriteLine($"rotate z=+1 around x by 90\n{r1}\n{r2} "); } // X Y { Matrix4 xrot = Matrix4.CreateRotationX(0.7853f); // demo that Matrix4.Create is the same values as mat4rotatex Matrix4 yrot = Matrix4.CreateRotationY(0.5f); Matrix4 res = Matrix4.Identity; res = res * xrot; res = res * yrot; System.Diagnostics.Debug.WriteLine("Rotate XY Manu =" + GLStaticsMatrix4.ApproxEquals(mat4r[id], res) + Environment.NewLine + mat4r[id].ToString()); id++; System.Diagnostics.Debug.WriteLine("Rotate XY Auto =" + GLStaticsMatrix4.ApproxEquals(mat4r[id], res) + Environment.NewLine + mat4r[id].ToString()); id++; res = Matrix4.Identity; res = res * yrot; res = res * xrot; System.Diagnostics.Debug.WriteLine("Rotate YX Manu =" + GLStaticsMatrix4.ApproxEquals(mat4r[id], res) + Environment.NewLine + mat4r[id].ToString()); id++; System.Diagnostics.Debug.WriteLine("Rotate YX Auto =" + GLStaticsMatrix4.ApproxEquals(mat4r[id], res) + Environment.NewLine + mat4r[id].ToString()); id++; } // mat4 translation { Matrix4 trans = Matrix4.CreateTranslation(10, 20, 30); System.Diagnostics.Debug.WriteLine("Translation =" + GLStaticsMatrix4.ApproxEquals(mat4r[id], trans) + Environment.NewLine + mat4r[id].ToString()); id++; } // mat4translation with matrix { Matrix4 yrot05 = Matrix4.CreateRotationY(0.5f); Matrix4 trans = Matrix4.CreateTranslation(10, 20, 30); Matrix4 rotplustrans = Matrix4.Mult(yrot05, trans); System.Diagnostics.Debug.WriteLine("Rot Translation =" + GLStaticsMatrix4.ApproxEquals(mat4r[id], rotplustrans) + Environment.NewLine + mat4r[id].ToString()); id++; } { Matrix4 trans = Matrix4.CreateTranslation(10, 20, 30); Matrix4 rotxm90 = Matrix4.CreateRotationX(-90f.Radians()); Matrix4 roty90 = Matrix4.CreateRotationY(90f.Radians()); Matrix4 mscale = Matrix4.CreateScale(1, 2, 3); Matrix4 res = Matrix4.Identity; res = res * mscale; res = res * rotxm90; res = res * roty90; res = res * trans; System.Diagnostics.Debug.WriteLine("Trans rot scale =" + GLStaticsMatrix4.ApproxEquals(mat4r[id], res) + Environment.NewLine + mat4r[id].ToString()); id++; //System.Diagnostics.Debug.WriteLine(transrotscale.ToString()); System.Diagnostics.Debug.WriteLine("Trans rot scale2 =" + GLStaticsMatrix4.ApproxEquals(mat4r[id], res) + Environment.NewLine + mat4r[id].ToString()); id++; } Vector4[] vec4r = vecoutbuffer.ReadVector4s(32 + 13 * 64, 2); // read all vec4 (N matrices between) { System.Diagnostics.Debug.WriteLine($"Vec4 {vec4r[0]}"); } { StringMatrix rox = new StringMatrix("1", "0", "0", "0", "0", "cx", "sx", "0", "0", "-sx", "cx", "0", "0", "0", "0", "1"); StringMatrix roxm90 = new StringMatrix("1", "0", "0", "0", "0", "0", "-1", "0", "0", "1", "0", "0", "0", "0", "0", "1"); StringMatrix roy = new StringMatrix("cy", "0", "-sy", "0", "0", "1", "0", "0", "sy", "0", "cy", "0", "0", "0", "0", "1"); StringMatrix res = StringMatrix.Mult(roxm90, roy); string r = res.ToString(true); System.Diagnostics.Debug.WriteLine($"{r}"); r = res.ToList(); System.Diagnostics.Debug.WriteLine($"{r}"); res = StringMatrix.Mult(rox, roy); r = res.ToString(true); System.Diagnostics.Debug.WriteLine($"{r}"); StringVector4 v4a = new StringVector4("a", "-1", "c", "d"); StringVector4 resv4 = StringMatrix.Mult(rox, v4a); r = resv4.ToString(true); System.Diagnostics.Debug.WriteLine($"{r}"); } // System.Di // agnostics.Debug.WriteLine(rotplustransscale.ToString()); }