/// <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> /// 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(); } }
/// <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 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> /// Create or update the texture with a new size and format /// </summary> /// <param name="width">Width</param> /// <param name="internalformat">Internal format, see InternalFormat in Texture base class</param> /// <param name="levels">Number of levels of this texture</param> public void CreateOrUpdateTexture(int width, SizedInternalFormat internalformat, int levels = 1) { if (Id < 0 || Width != width || MipMapLevels != levels) // if not there, or changed, we can't just replace it, size is fixed. Delete it { if (Id >= 0) { Dispose(); } InternalFormat = internalformat; Width = width; Height = 1; Depth = levels; GL.CreateTextures(TextureTarget.Texture1D, 1, out int id); GLStatics.RegisterAllocation(typeof(GLTexture1D)); GLStatics.Check(); Id = id; GL.TextureStorage1D(Id, levels, InternalFormat, Width); } }
/// <summary> /// Compile. The codelisting is glsl with the following extensions: /// #include resourcename /// .. resourcename can either be a reference to an OFC glsl file, from the GL4 root, such as Shaders.Volumetric.volumetricgeoshader.glsl /// .. or it can be a fully qualified resource reference: TestOpenTk.Volumetrics.volumetricgeo3.glsl /// .. or it can be a partial resource reference from a include modules path (no . at the end, fully qualified : TestOpenTk.Volumetrics) /// .. or it can be a fully qualified filename (no quotes) /// .. or a partial path from one of the static includepaths /// const values: /// .. constvalues allow you to override definitions in the script for const type var = value /// .. declare your variables in glsl like this (const int iterations = 10 for example) /// .. then include in call a list of (string,value) pairs to set the const values to (new object[] {"iterations",20}) /// .. glsl types: int, float (passed in as float or double), System.Drawing.Color, bool, /// .. vec2 (OpenTK.Vector2), vec3 (OpenTK.Vector3), vec4 (as OpenTK.Vector4) /// .. vec4[] (OpenTK.Vector4[]), Color[] ///</summary> public string Compile(string codelisting, Object[] constvalues = null, string completeoutfile = null) // string return gives any errors { Id = GL.CreateShader(type); GLStatics.RegisterAllocation(typeof(GLShader)); string source = PreprocessShaderCode(codelisting, constvalues, completeoutfile); GL.ShaderSource(Id, source); GL.CompileShader(Id); string CompileReport = GL.GetShaderInfoLog(Id); if (CompileReport.HasChars()) { GL.DeleteShader(Id); Id = -1; int opos = CompileReport.IndexOf("0("); if (opos != -1) { int opose = CompileReport.IndexOf(")", opos); if (opose != -1) // lets help ourselves by reporting the source.. since the source can be obscure. { int?lineno = CompileReport.Substring(opos + 2, opose - opos - 2).InvariantParseIntNull(); if (lineno.HasValue) { CompileReport = CompileReport + Environment.NewLine + source.LineMarking(lineno.Value - 5, 10, "##0", lineno.Value); } } } return(CompileReport); } return(null); }
/// <summary> /// Constructor, set up the query. /// See <href>"https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glBeginQueryIndexed.xhtml"</href> /// </summary> /// <param name="target">Target may be one of GL_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED_CONSERVATIVE, GL_TIME_ELAPSED, GL_TIMESTAMP, GL_PRIMITIVES_GENERATED or GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN. (use openTK IDs)</param> /// <param name="index">index of query, normally 0</param> /// <param name="createnow">Create query now, or wait until Execute</param> /// <param name="querybuffer">Optional, for GLOperationEndQuery, a buffer to store the query data into. Caller must allocate buffer</param> public GLOperationQuery(QueryTarget target, int index = 0, bool createnow = false, GLBuffer querybuffer = null) { this.Target = target; this.Index = index; this.QueryBuffer = querybuffer; int id = 0; if (createnow) { GL.CreateQueries(Target, 1, out id); } else { GL.GenQueries(1, out id); } GLStatics.RegisterAllocation(typeof(GLOperationQuery)); System.Diagnostics.Debug.Assert(id != 0); GLStatics.Check(); this.Id = id; }
/// <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 /// mipmaplevels does not apply if multisample > 0 /// Rgba8 is the normal one to pick /// </summary> /// <param name="width">Width of texture</param> /// <param name="height">Height of texture</param> /// <param name="internalformat">Internal format, see InternalFormat in Texture base class</param>/// /// <param name="mipmaplevels">Mip map levels wanted</param> /// <param name="multisample">Multisample count, normally 0</param> /// <param name="fixedmultisampleloc">Fix multisample positions in the same place for all texel in image</param> public void CreateOrUpdateTexture(int width, int height, SizedInternalFormat internalformat, int mipmaplevels = 1, int multisample = 0, bool fixedmultisampleloc = false) { // if not there, or changed, we can't just replace it, size is fixed. Delete it if (Id < 0 || Width != width || Height != height || mipmaplevels != MipMapLevels || multisample != MultiSample) { if (Id >= 0) // dispose if set { Dispose(); } InternalFormat = internalformat; Width = width; Height = height; MipMapLevels = mipmaplevels; MultiSample = multisample; GL.CreateTextures(MultiSample > 0 ? TextureTarget.Texture2DMultisample : TextureTarget.Texture2D, 1, out int id); GLStatics.RegisterAllocation(typeof(GLTexture2D)); GLStatics.Check(); Id = id; if (MultiSample > 0) { GL.TextureStorage2DMultisample(Id, MultiSample, InternalFormat, Width, Height, fixedmultisampleloc); } else { GL.TextureStorage2D(Id, mipmaplevels, InternalFormat, Width, Height); } SetMinMagFilter(); 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 /// mipmaplevels does not apply if multisample > 0 /// Rgba8 is the normal one to pick /// </summary> /// <param name="width">Width of texture</param> /// <param name="height">Height 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> /// <param name="multisample">Multisample count, normally 0</param> /// <param name="fixedmultisampleloc">Fix multisample positions in the same place for all texel in image</param> public void CreateOrUpdateTexture(int width, int height, int depth, SizedInternalFormat internalformat, int wantedmipmaplevels = 1, int multisample = 0, bool fixedmultisampleloc = false) { if (Id < 0 || Width != width || Height != height || Depth != depth || wantedmipmaplevels != MipMapLevels || MultiSample != multisample) { if (Id >= 0) { Dispose(); } InternalFormat = internalformat; Width = width; Height = height; Depth = depth; MipMapLevels = wantedmipmaplevels; MultiSample = multisample; GL.CreateTextures(MultiSample > 0 ? TextureTarget.Texture2DMultisampleArray : TextureTarget.Texture2DArray, 1, out int id); GLStatics.RegisterAllocation(typeof(GLTexture2DArray)); GLStatics.Check(); Id = id; if (MultiSample > 0) { GL.TextureStorage3DMultisample(Id, MultiSample, InternalFormat, Width, Height, Depth, fixedmultisampleloc); } else { GL.TextureStorage3D(Id, wantedmipmaplevels, InternalFormat, Width, Height, Depth); } SetMinMagFilter(); GLStatics.Check(); } }
/// <summary> Create a empty pipeline shader</summary> public GLShaderPipeline() { pipelineid = GL.GenProgramPipeline(); GLStatics.RegisterAllocation(typeof(GLShaderPipeline)); }
/// <summary> Construct a vertex array </summary> public GLVertexArray() { Id = GL.GenVertexArray(); context = GLStatics.GetContext(); GLStatics.RegisterAllocation(typeof(GLVertexArray)); }
/// <summary> Construct a Transform Feedback object </summary> public GLTransformFeedback() { Id = GL.GenTransformFeedback(); GLStatics.RegisterAllocation(typeof(GLTransformFeedback)); GLStatics.Check(); }
/// <summary>Make a new fence, with condition and wait flags /// see <href>https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glFenceSync.xhtml</href> /// </summary> /// <param name="synccondition">Must be SyncCondition.SyncGpuCommandsComplete</param> /// <param name="waitflags">Must be 0</param> public GLFenceSync(SyncCondition synccondition = SyncCondition.SyncGpuCommandsComplete, WaitSyncFlags waitflags = WaitSyncFlags.None) { Id = GL.FenceSync(synccondition, waitflags); GLStatics.RegisterAllocation(typeof(GLFenceSync)); }
/// <summary> Construct a buffer </summary> public GLRenderBuffer() { Id = GL.GenRenderbuffer(); GLStatics.RegisterAllocation(typeof(GLRenderBuffer)); }
/// <summary>Create a program</summary> public GLProgram() { Id = GL.CreateProgram(); GLStatics.RegisterAllocation(typeof(GLProgram)); shaders = new List <GLShader>(); }
/// <summary> Create a pipeline shader from binary</summary> public GLShaderPipeline(byte[] bin, BinaryFormat binformat) { pipelineid = GL.GenProgramPipeline(); GLStatics.RegisterAllocation(typeof(GLShaderPipeline)); Load(bin, binformat); }
///<summary> Make a new frame buffer and get ID </summary> public GLFrameBuffer() { GL.CreateFramebuffers(1, out int id); GLStatics.RegisterAllocation(typeof(GLFrameBuffer)); Id = id; }