예제 #1
0
        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));
        }
예제 #2
0
        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;
        }
예제 #3
0
        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");
        }
예제 #4
0
        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);
        }
예제 #6
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");
        }
예제 #7
0
        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;
        }
예제 #8
0
        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");
        }
예제 #9
0
        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));
        }
예제 #10
0
        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;
        }
예제 #11
0
        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");
        }