/// <summary> /// Create or update texture using this pixel format - special. Used for depth or stencil buffers /// See <href>https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glTexImage2D.xhtml</href> /// </summary> /// <param name="width">Width of texture</param> /// <param name="height">Height of texture</param> /// <param name="pixelinternalformat">Pixel internal format</param> /// <param name="pixelformat">Pixel format</param> /// <param name="pixeltype">Pixel type</param> public void CreateOrUpdateTexturePixelFormat(int width, int height, PixelInternalFormat pixelinternalformat, PixelFormat pixelformat, PixelType pixeltype) // make with a pixel format.. { if (Id < 0 || Width != width || Height != height) // if not there, or changed, we can't just replace it, size is fixed. Delete it { if (Id >= 0) { Dispose(); } InternalFormat = 0; // PixelInternalFormat does not fit within this, so zero it Width = width; Height = height; MipMapLevels = 1; GL.CreateTextures(TextureTarget.Texture2D, 1, out int id); GLStatics.RegisterAllocation(typeof(GLTexture2D)); GLStatics.Check(); Id = id; GL.BindTexture(TextureTarget.Texture2D, Id); GL.TexImage2D(TextureTarget.Texture2D, 0, pixelinternalformat, width, height, 0, pixelformat, pixeltype, (IntPtr)0); // we don't actually load data in, so its a null ptr. GLStatics.Check(); } }
/// <summary> Stop a read or write sequence, release buffer back to use </summary> public void StopReadWrite() { System.Diagnostics.Debug.Assert(context == GLStatics.GetContext(), "Context incorrect"); // safety GL.UnmapNamedBuffer(Id); mapmode = MapMode.None; GLStatics.Check(); }
/// <summary>Zero the buffer from this position and length</summary> public void Zero(int pos, int length) { System.Diagnostics.Debug.Assert(context == GLStatics.GetContext(), "Context incorrect"); // safety System.Diagnostics.Debug.Assert(Length != 0 && pos >= 0 && length <= Length && pos + length <= Length); GL.ClearNamedBufferSubData(Id, PixelInternalFormat.R32ui, (IntPtr)pos, length, PixelFormat.RedInteger, PixelType.UnsignedInt, (IntPtr)0); GLStatics.Check(); }
/// <summary> /// 1D Textures from the bound read framebuffer (from x/y) into this texture at xoffset /// See <href>https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glCopyTexSubImage2D.xhtml</href> /// </summary> /// <param name="miplevel">Mip Level to store data into</param> /// <param name="xoffset">Left offset to store in the texture</param> /// <param name="x">Left corner to copy</param> /// <param name="y">Bottom corner to copy</param> /// <param name="width">Width to copy</param> public void CopyFromReadFrameBuffer1d(int miplevel, int xoffset, int x, int y, int width) { System.Diagnostics.Debug.Assert(this is GLTexture1D); System.Diagnostics.Debug.Assert(context == GLStatics.GetContext(), "Context incorrect"); GL.CopyTextureSubImage1D(Id, miplevel, xoffset, x, y, width); GLStatics.Check(); }
// ///<summary> Read from bound Read Frame buffer target in this pixel format and type. Bufsize indicates amount of space needed for byte array </summary> public void ReadPixels(ReadBufferMode src, int x0, int y0, int x1, int y1, PixelFormat format, PixelType type, int bufsize) { GL.ReadBuffer(src); byte[] array = new byte[bufsize]; GL.ReadnPixels(x0, y0, x1, y1, format, type, array.Length, array); GLStatics.Check(); }
/// <summary> /// 2D Arrays or 3D from the bound read framebuffer (from sx/sy) into this texture at x/y -2D Array or 3D /// See <href>https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glCopyTexSubImage3D.xhtml</href> /// </summary> /// <param name="miplevel">Mip Level to store data into</param> /// <param name="xoffset">Left offset to store in the texture</param> /// <param name="yoffset">Bottom offset to store in the texture</param> /// <param name="zoffset">Depth offset to store in the texture</param> /// <param name="x">Left corner to copy</param> /// <param name="y">Bottom corner to copy</param> /// <param name="width">Width to copy</param> /// <param name="height">Height to copy</param> public void CopyFromReadFrameBuffer2da3d(int miplevel, int xoffset, int yoffset, int zoffset, int x, int y, int width, int height) { System.Diagnostics.Debug.Assert(this is GLTexture2DArray || this is GLTexture3D); System.Diagnostics.Debug.Assert(context == GLStatics.GetContext(), "Context incorrect"); GL.CopyTextureSubImage3D(Id, miplevel, xoffset, yoffset, zoffset, x, y, width, height); GLStatics.Check(); }
// 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); }
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> Constructor, create a time query</summary> public GLOperationQueryTimeStamp() { this.Id = GL.GenQuery(); System.Diagnostics.Debug.Assert(Id != 0); GLStatics.RegisterAllocation(typeof(GLOperationQueryTimeStamp)); GLStatics.Check(); }
/// <summary> /// Create of update the texture with a new size and format /// You can call as many times to create textures. Only creates one if required /// Rgba8 is the normal one to pick /// </summary> /// <param name="width">Width of texture</param> /// <param name="depth">Number of levels of texture</param> /// <param name="internalformat">Internal format, see InternalFormat in Texture base class</param>/// /// <param name="wantedmipmaplevels">Mip map levels wanted in texture</param> public void CreateOrUpdateTexture(int width, int depth, SizedInternalFormat internalformat, int wantedmipmaplevels = 1) { if (Id < 0 || Width != width || Depth != depth || wantedmipmaplevels != MipMapLevels) { if (Id >= 0) { Dispose(); } InternalFormat = internalformat; Width = width; Height = 1; Depth = depth; MipMapLevels = wantedmipmaplevels; GL.CreateTextures(TextureTarget.Texture1DArray, 1, out int id); GLStatics.RegisterAllocation(typeof(GLTexture2DArray)); GLStatics.Check(); Id = id; GL.TextureStorage2D(Id, wantedmipmaplevels, InternalFormat, Width, Height); SetMinMagFilter(); GLStatics.Check(); } }
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, false); GLStatics.Check(); //GLStatics.Flush(); var t1 = ts1.GetCounter(); var t2 = ts2.GetCounter(); System.Diagnostics.Debug.WriteLine($"Time Taken {t2 - t1} ns"); var t = sync.ClientWait(ClientWaitSyncFlags.SyncFlushCommandsBit, 100000000); System.Diagnostics.Debug.WriteLine($"Sync {t}"); sync.Dispose(); 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> Attach a 2D texture to frame buffer on colourtarget and mipmaplevel, to a specific layer </summary> public void AttachColorLayered(GLTexture2DArray tex, int colourtarget = 0, int mipmaplevel = 0, int layer = 0) // not tested.. page 401 { ColorTarget = colourtarget; Width = tex.Width; Height = tex.Height; GL.NamedFramebufferTextureLayer(Id, FramebufferAttachment.ColorAttachment0 + ColorTarget, tex.Id, mipmaplevel, layer); GLStatics.Check(); }
///<summary> Attach a 2D texture to frame buffer on colourtarget and mipmaplevel </summary> public void AttachColor(GLTexture2D tex, int colourtarget = 0, int mipmaplevel = 0) { ColorTarget = colourtarget; Width = tex.Width; Height = tex.Height; GL.NamedFramebufferTexture(Id, FramebufferAttachment.ColorAttachment0 + ColorTarget, tex.Id, mipmaplevel); GLStatics.Check(); }
/// <summary> Get binary. Must have linked with wantbinary </summary> public byte[] GetBinary(out BinaryFormat binformat) { GL.GetProgram(Id, (GetProgramParameterName)0x8741, out int len); byte[] array = new byte[len]; GL.GetProgramBinary(Id, len, out int binlen, out binformat, array); GLStatics.Check(); return(array); }
/// <summary> Allocate a non multisampled buffer of width and height, and bind to target Renderbuffer </summary> public void Allocate(RenderbufferStorage storage, int width, int height) { Width = width; Height = height; GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, Id); GL.NamedRenderbufferStorage(Id, storage, Width, Height); GLStatics.Check(); }
/// <summary> Add a pipeline shader of shadertype </summary> public void Add(IGLPipelineComponentShader pipelineshader, ShaderType shadertype) { System.Diagnostics.Debug.Assert(!shaders.ContainsKey(shadertype)); shaders[shadertype] = pipelineshader; pipelineshader.References++; GL.UseProgramStages(pipelineid, convmask[shadertype], pipelineshader.Id); GLStatics.Check(); }
/// <summary> Skip pointer forward </summary> public void Skip(int p) { System.Diagnostics.Debug.Assert(mapmode != MapMode.None); CurrentPtr += p; CurrentPos += p; System.Diagnostics.Debug.Assert(CurrentPos <= Length); GLStatics.Check(); }
///<summary>Create an empty buffer of this standard, default is std130. Standard defines the layout of members of the buffer. See OpenGL</summary> public GLBuffer(bool std430 = false) : base(std430) { GL.CreateBuffers(1, out int id); // this actually makes the buffer, GenBuffer does not - just gets a name GLStatics.RegisterAllocation(typeof(GLBuffer)); GLStatics.Check(); Id = id; context = GLStatics.GetContext(); }
///<summary> Unbinds from query buffer</summary> static public void UnbindQuery() { if (querybindindex != -1) { GL.BindBuffer(BufferTarget.QueryBuffer, 0); // 0 is the unbind value GLStatics.Check(); querybindindex = -1; } }
/// <summary> Allocate a multisample buffer of width, height, and samples depth, and bind to target Renderbuffer </summary> public void AllocateMultisample(RenderbufferStorage storage, int width, int height, int samples) { Width = width; Height = height; Samples = samples; GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, Id); GL.NamedRenderbufferStorageMultisample(Id, Samples, storage, Width, Height); GLStatics.Check(); }
/// <summary> Get the sync status of the fence. </summary> /// <param name="paraname">Get SyncCondition, SyncStatus, SyncFlags or ObjectType. Default is to get sync status</param> /// <returns>Returns an array of sync properties. Dependent on fence type</returns> public int[] Get(SyncParameterName paraname = SyncParameterName.SyncStatus) { int[] array = new int[20]; GL.GetSync(Id, paraname, array.Length, out int len, array); GLStatics.Check(); int[] res = new int[len]; Array.Copy(array, res, len); return(res); }
///<summary> Changes GL target for rendering to this frame buffer, sets viewport, clears to colourback </summary> public void BindColor(OpenTK.Graphics.Color4 colourback) { GL.NamedFramebufferDrawBuffer(Id, DrawBufferMode.ColorAttachment0 + ColorTarget); // attach the FB to draw buffer target GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, Id); // bind the FB to the system GL.Viewport(new System.Drawing.Rectangle(0, 0, Width, Height)); // set the viewport GL.ClearColor(colourback); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); // clear the FB GLStatics.Check(); }
/// <summary> Called by render list and executes the operation </summary> public override void Execute(GLMatrixCalc c) { if (QueryBuffer != null) { QueryBuffer.BindQuery(); } GL.BeginQueryIndexed(Target, Index, Id); GLStatics.Check(); }
/// <summary> /// Compile the compute program /// </summary> /// <param name="codelisting">The code</param> /// <param name="constvalues">List of constant values to use. Set of {name,value} pairs</param> /// <param name="saveable">True if want to save to binary</param> /// <param name="completeoutfile">If non null, output the post processed code listing to this file</param> public void CompileLink(string codelisting, object[] constvalues = null, bool saveable = false, string completeoutfile = null) { Program = new GLProgram(); string ret = Program.Compile(ShaderType.ComputeShader, codelisting, constvalues, completeoutfile); System.Diagnostics.Debug.Assert(ret == null, "Compute Shader", ret); ret = Program.Link(wantbinary: saveable); System.Diagnostics.Debug.Assert(ret == null, "Link", ret); GLStatics.Check(); }
/// <summary> /// From any type of ImageTarget into this - All types /// See <href>https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glCopyImageSubData.xhtml</href> /// </summary> /// <param name="srcid">Texture or Renderbuffer source</param> /// <param name="srcTarget">Source image type</param> /// <param name="srcmiplevel">Mipmap level to copy from</param> /// <param name="sx">Source X</param> /// <param name="sy">Source Y</param> /// <param name="sz">Source Z level</param> /// <param name="dmiplevel">Destination mip level</param> /// <param name="dx">Destination X</param> /// <param name="dy">Destination Y</param> /// <param name="dz">Destination Z (0 for 2D/1D</param> /// <param name="width">Destination Width</param> /// <param name="height">Destination Height</param> public void CopyFrom(int srcid, ImageTarget srcTarget, int srcmiplevel, int sx, int sy, int sz, int dmiplevel, int dx, int dy, int dz, int width, int height) { System.Diagnostics.Debug.Assert(context == GLStatics.GetContext(), "Context incorrect"); // not sure, according to spec, the dest target may just need to be a texture type.. ImageTarget it = this is GLTexture2D ? ImageTarget.Texture2D : this is GLTexture2DArray ? ImageTarget.Texture2DArray : this is GLTexture1D ? ImageTarget.Texture1D : ImageTarget.Texture3D; GL.CopyImageSubData(srcid, srcTarget, srcmiplevel, sx, sy, sz, Id, it, dmiplevel, dx, dy, dz, width, height, 1); GLStatics.Check(); }
/// <summary>Bind buffer to vertext array at this bindingindex, with the start position stride and divisor</summary> public void Bind(GLVertexArray va, int bindingindex, int start, int stride, int divisor = 0) // set buffer binding to a VA { System.Diagnostics.Debug.Assert(context == GLStatics.GetContext(), "Context incorrect"); // safety System.Diagnostics.Debug.Assert(mapmode == MapMode.None); // catch unmap missing. Since binding to VA can be done before buffer is full, then don't check BufferSize va.Bind(); GL.BindVertexBuffer(bindingindex, Id, (IntPtr)start, stride); // this buffer to binding index GL.VertexBindingDivisor(bindingindex, divisor); GLStatics.Check(); //System.Diagnostics.Debug.WriteLine("BUFBIND " + bindingindex + " To B" + Id + " pos " + start + " stride " + stride + " divisor " + divisor); }
/// <summary>Bind buffer to indirect binding point</summary> public void BindIndirect() { System.Diagnostics.Debug.Assert(context == GLStatics.GetContext(), "Context incorrect"); // safety System.Diagnostics.Debug.Assert(mapmode == MapMode.None && Length > 0); // catch unmap missing or nothing in buffer //if (indirectbindindex != Id) // removed for testing { GL.BindBuffer(BufferTarget.DrawIndirectBuffer, Id); GLStatics.Check(); indirectbindindex = Id; } }
/// <summary>Bind buffer to parameter binding point</summary> public void BindParameter() { System.Diagnostics.Debug.Assert(context == GLStatics.GetContext(), "Context incorrect"); // safety System.Diagnostics.Debug.Assert(mapmode == MapMode.None && Length > 0); // catch unmap missing or nothing in buffer // if (parameterbindindex != Id) // removed for testing { GL.BindBuffer((BufferTarget)0x80ee, Id); // fudge due to ID not being there in 3.3.2 GLStatics.Check(); parameterbindindex = Id; } }
///<summary> Bind to query buffer</summary> public void BindQuery() { System.Diagnostics.Debug.Assert(context == GLStatics.GetContext(), "Context incorrect"); // safety System.Diagnostics.Debug.Assert(mapmode == MapMode.None && Length > 0); // catch unmap missing or nothing in buffer if (querybindindex != Id) { GL.BindBuffer(BufferTarget.QueryBuffer, Id); GLStatics.Check(); querybindindex = Id; } }
/// <summary>Fill with floats. length = -1 use floats.length, else take a subset starting at zero index </summary> public void Fill(float[] floats, int length = -1) { length = (length == -1) ? floats.Length : length; if (length > 0) { int datasize = length * sizeof(float); int posv = AlignArray(sizeof(float), datasize); GL.NamedBufferSubData(Id, (IntPtr)posv, datasize, floats); GLStatics.Check(); } }