public static Texture2d Create(Color4 color, string description, int width = 1, int height = 1, TextureOptions textureOptions = null) { textureOptions = textureOptions ?? TextureOptions.Default; var textureId = GL.GenTexture(); try { var data = new int[width * height]; for (int i = 0; i < width * height; i++) { data[i] = color.ToRgba(); } DrawState.BindTexture(textureId); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, width, height, 0, OpenTK.Graphics.OpenGL.PixelFormat.Rgba, PixelType.UnsignedByte, data); if (textureOptions.GenerateMipmaps) { GL.GenerateMipmap(GenerateMipmapTarget.Texture2D); GL.Finish(); } DrawState.CheckError("specifying texture"); textureOptions.ApplyParameters(TextureTarget.Texture2D); } catch (Exception) { GL.DeleteTexture(textureId); DrawState.UnbindTexture(textureId); throw; } return(new Texture2d(textureId, width, height, description)); }
public void Begin(bool clear = true) { if (started) { throw new InvalidOperationException("Already started"); } DrawState.FlushRenderer(); validate(); previousViewport = DrawState.Viewport; GL.GetInteger(GetPName.FramebufferBinding, out previousFrameBufferId); GL.BindFramebuffer(FramebufferTarget.Framebuffer, frameBufferId); GL.DrawBuffer(DrawBufferMode.ColorAttachment0); DrawState.CheckError("binding fbo"); DrawState.Viewport = new Rectangle(0, 0, width, height); if (clear) { // XXX need GL.DepthMask(true); to clear depth, but setting it here may cause issues with renderstate cache GL.ClearColor(0, 0, 0, 0); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit); } started = true; }
private void initialize(int width, int height) { Width = width; Height = height; PixelInternalFormat pixelInternalFormat = (PixelInternalFormat)storage; PixelFormat pixelFormat; PixelType pixelType; switch (storage) { case RenderbufferStorage.DepthComponent: case RenderbufferStorage.DepthComponent16: case RenderbufferStorage.DepthComponent24: case RenderbufferStorage.DepthComponent32: case RenderbufferStorage.DepthComponent32f: pixelFormat = PixelFormat.DepthComponent; pixelType = PixelType.Float; break; case RenderbufferStorage.DepthStencil: case RenderbufferStorage.Depth32fStencil8: case RenderbufferStorage.Depth24Stencil8: pixelFormat = PixelFormat.DepthStencil; pixelType = PixelType.UnsignedInt248; break; case RenderbufferStorage.StencilIndex1: case RenderbufferStorage.StencilIndex4: case RenderbufferStorage.StencilIndex8: case RenderbufferStorage.StencilIndex16: pixelFormat = PixelFormat.StencilIndex; pixelType = PixelType.Float; break; default: pixelFormat = PixelFormat.Rgba; pixelType = PixelType.UnsignedByte; break; } var textureId = GL.GenTexture(); Texture = new Texture2d(textureId, Width, Height, "rendertexture"); DrawState.BindPrimaryTexture(textureId); GL.TexImage2D(TextureTarget.Texture2D, 0, pixelInternalFormat, Width, Height, 0, pixelFormat, pixelType, IntPtr.Zero); DrawState.CheckError("creating a render texture's texture"); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); DrawState.UnbindTexture(textureId); Debug.Print(width + "x" + height + " " + storage + " render texture created"); }
public void Update(Bitmap bitmap, int x, int y) { DrawState.BindPrimaryTexture(textureId, TexturingModes.Texturing2d); var bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); GL.TexSubImage2D(TextureTarget.Texture2D, 0, x, y, bitmapData.Width, bitmapData.Height, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, bitmapData.Scan0); GL.Finish(); bitmap.UnlockBits(bitmapData); DrawState.CheckError("updating texture"); }
protected override void initializeVertexBuffer() { base.initializeVertexBuffer(); vertexBufferSize = minRenderableVertexCount * vertexDeclaration.VertexSize; GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBufferId); GL.BufferStorage(BufferTarget.ArrayBuffer, (IntPtr)vertexBufferSize, IntPtr.Zero, BufferStorageFlags.MapWriteBit | BufferStorageFlags.MapPersistentBit | BufferStorageFlags.MapCoherentBit); bufferPointer = GL.MapBufferRange(BufferTarget.ArrayBuffer, IntPtr.Zero, (IntPtr)vertexBufferSize, BufferAccessMask.MapWriteBit | BufferAccessMask.MapPersistentBit | BufferAccessMask.MapCoherentBit); DrawState.CheckError("mapping vertex buffer", bufferPointer == null); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); }
public void ApplyParameters(TextureTarget target) { if (TextureLodBias != 0) { GL.TexEnv(TextureEnvTarget.TextureFilterControl, TextureEnvParameter.TextureLodBias, TextureLodBias); } GL.TexParameter(target, TextureParameterName.TextureMinFilter, (int)TextureMinFilter); GL.TexParameter(target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter); GL.TexParameter(target, TextureParameterName.TextureWrapS, (int)TextureWrapS); GL.TexParameter(target, TextureParameterName.TextureWrapT, (int)TextureWrapT); DrawState.CheckError("applying texture parameters"); }
public void Begin(bool clear = true) { if (started) { throw new InvalidOperationException("Already started"); } DrawState.FlushRenderer(); if (!initialized) { initialize(); } previousViewport = DrawState.Viewport; GL.GetInteger(GetPName.FramebufferBinding, out previousFrameBufferId); GL.BindFramebuffer(FramebufferTarget.Framebuffer, frameBufferId); if (renderTextures.Length == 1) { GL.DrawBuffer(DrawBufferMode.ColorAttachment0); } else if (renderTextures.Length > 1) { var buffers = new DrawBuffersEnum[renderTextures.Length]; for (int i = 0, size = renderTextures.Length; i < size; i++) { Debug.Assert(DrawBuffersEnum.ColorAttachment0 + i <= DrawBuffersEnum.ColorAttachment15); buffers[i] = DrawBuffersEnum.ColorAttachment0 + i; } GL.DrawBuffers(buffers.Length, buffers); } DrawState.CheckError("binding fbo"); DrawState.Viewport = new Rectangle(0, 0, width, height); if (clear) { GL.ClearColor(0, 0, 0, 0); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit); } started = true; }
public void Update(Bitmap bitmap, int x, int y) { if (bitmap.Width < 1 || bitmap.Height < 1) { throw new InvalidOperationException($"Invalid bitmap size: {bitmap.Width}x{bitmap.Height}"); } if (x + bitmap.Width > Width || y + bitmap.Height > Height) { throw new InvalidOperationException($"Invalid update bounds: {bitmap.Width}x{bitmap.Height} at {x},{y} overflows {Width}x{Height}"); } DrawState.BindPrimaryTexture(textureId, TexturingModes.Texturing2d); var bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); GL.TexSubImage2D(TextureTarget.Texture2D, 0, x, y, bitmapData.Width, bitmapData.Height, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, bitmapData.Scan0); GL.Finish(); bitmap.UnlockBits(bitmapData); DrawState.CheckError("updating texture"); }
public static Texture2d Load(Bitmap bitmap, string description, TextureOptions textureOptions = null) { if (bitmap == null) { throw new ArgumentNullException(nameof(bitmap)); } textureOptions = textureOptions ?? TextureOptions.Default; var sRgb = textureOptions.Srgb && DrawState.ColorCorrected; var textureId = GL.GenTexture(); try { DrawState.BindTexture(textureId); var bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); GL.TexImage2D(TextureTarget.Texture2D, 0, sRgb ? PixelInternalFormat.SrgbAlpha : PixelInternalFormat.Rgba, bitmapData.Width, bitmapData.Height, 0, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, bitmapData.Scan0); if (textureOptions.GenerateMipmaps) { GL.GenerateMipmap(GenerateMipmapTarget.Texture2D); } GL.Finish(); bitmap.UnlockBits(bitmapData); DrawState.CheckError("specifying texture"); textureOptions.ApplyParameters(TextureTarget.Texture2D); } catch (Exception) { GL.DeleteTexture(textureId); DrawState.UnbindTexture(textureId); throw; } return(new Texture2d(textureId, bitmap.Width, bitmap.Height, description)); }
private void initialize() { GL.GetInteger(GetPName.FramebufferBinding, out previousFrameBufferId); // Create the framebuffer frameBufferId = GL.GenFramebuffer(); GL.BindFramebuffer(FramebufferTarget.Framebuffer, frameBufferId); // Attach textures for (int i = 0, size = renderTextures.Length; i < size; i++) { var renderTexture = renderTextures[i]; if (i == 0) { width = renderTexture.Width; height = renderTexture.Height; } else if (width != renderTexture.Width || height != renderTexture.Height) { throw new InvalidOperationException("Render textures must have the same size"); } var textureId = renderTexture.Texture.TextureId; Debug.Assert(FramebufferAttachment.ColorAttachment0 + i <= FramebufferAttachment.ColorAttachment15); GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0 + i, TextureTarget.Texture2D, textureId, 0); } if (depthStencilTexture != null) { if (width != depthStencilTexture.Width || height != depthStencilTexture.Height) { throw new InvalidOperationException("The depth / stencil texture must have the same size as the render textures"); } var textureId = depthStencilTexture.Texture.TextureId; switch (depthStencilTexture.Storage) { case RenderbufferStorage.DepthComponent: case RenderbufferStorage.DepthComponent16: case RenderbufferStorage.DepthComponent24: case RenderbufferStorage.DepthComponent32: case RenderbufferStorage.DepthComponent32f: GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, TextureTarget.Texture2D, textureId, 0); break; case RenderbufferStorage.DepthStencil: case RenderbufferStorage.Depth24Stencil8: case RenderbufferStorage.Depth32fStencil8: GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthStencilAttachment, TextureTarget.Texture2D, textureId, 0); break; case RenderbufferStorage.StencilIndex1: case RenderbufferStorage.StencilIndex4: case RenderbufferStorage.StencilIndex8: case RenderbufferStorage.StencilIndex16: GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.StencilAttachment, TextureTarget.Texture2D, textureId, 0); break; default: throw new NotSupportedException(depthStencilTexture.Storage + " storage isn't supported for the depth / stencil texture."); } } // Check var status = GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer); if (status != FramebufferErrorCode.FramebufferComplete) { throw new Exception("frame buffer couldn't be constructed: " + status); } DrawState.CheckError("initializing multi render target"); GL.BindFramebuffer(FramebufferTarget.Framebuffer, previousFrameBufferId); Debug.Print(width + "x" + height + " multi render target created"); initialized = true; }
private void initialize() { textureId = GL.GenTexture(); texture = new Texture2d(textureId, width, height, "rendertarget"); DrawState.BindPrimaryTexture(textureId); GL.TexImage2D(TextureTarget.Texture2D, 0, internalFormat, width, height, 0, pixelFormat, pixelType, IntPtr.Zero); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)textureMagFilter); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)textureMinFilter); GL.GetInteger(GetPName.FramebufferBinding, out previousFrameBufferId); frameBufferId = GL.GenFramebuffer(); GL.BindFramebuffer(FramebufferTarget.Framebuffer, frameBufferId); GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D, textureId, 0); DrawState.CheckError("creating fbo"); if (renderBufferType != null) { renderBufferId = GL.GenRenderbuffer(); GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, renderBufferId); GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, renderBufferType.Value, width, height); switch (renderBufferType.Value) { case RenderbufferStorage.DepthComponent: case RenderbufferStorage.DepthComponent16: case RenderbufferStorage.DepthComponent24: case RenderbufferStorage.DepthComponent32: case RenderbufferStorage.DepthComponent32f: GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, RenderbufferTarget.Renderbuffer, renderBufferId); break; case RenderbufferStorage.DepthStencil: case RenderbufferStorage.Depth24Stencil8: case RenderbufferStorage.Depth32fStencil8: GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthStencilAttachment, RenderbufferTarget.Renderbuffer, renderBufferId); break; case RenderbufferStorage.StencilIndex1: case RenderbufferStorage.StencilIndex4: case RenderbufferStorage.StencilIndex8: case RenderbufferStorage.StencilIndex16: GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.StencilAttachment, RenderbufferTarget.Renderbuffer, renderBufferId); break; default: throw new NotSupportedException("renderBufferType " + renderBufferType.Value + " isn't supported."); } } var status = GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer); if (status != FramebufferErrorCode.FramebufferComplete) { throw new Exception("frame buffer couldn't be constructed: " + status); } DrawState.UnbindTexture(textureId); GL.BindFramebuffer(FramebufferTarget.Framebuffer, previousFrameBufferId); Debug.Print(width + "x" + height + " render target created"); }