Пример #1
0
        public override bool Bind()
        {
            Debug.Assert(!isDisposed);

            Upload();

            if (textureId <= 0)
            {
                return(false);
            }

            if (IsTransparent)
            {
                return(false);
            }

            OsuGlControl.BindTexture(textureId);

            if (internalWrapMode != WrapMode)
            {
                updateWrapMode();
            }

            return(true);
        }
Пример #2
0
        internal void Unbind()
        {
            if (!bound)
            {
                return;
            }

            if (OsuGlControl.CanUseFBO)
            {
                currentFrameBuffer = lastFrameBuffer;
                GL.BindFramebuffer(FramebufferTarget.Framebuffer, lastFrameBuffer);
            }
            else
            {
                //Copy from backbuffer
                OsuGlControl.BindTexture(Texture.TextureId);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear);

                GL.CopyTexSubImage2D(All.Texture2D, 0, (int)copyDstPosition.X, (int)copyDstPosition.Y, copySrcRectangle.X, copySrcRectangle.Y, copySrcRectangle.Width, copySrcRectangle.Height);
            }

            if (OsuGlControl.Viewport != prevViewport)
            {
                OsuGlControl.ResetViewport(prevViewport);
                OsuGlControl.ResetOrtho(prevOrtho);
            }

            bound = false;
        }
Пример #3
0
        internal RenderTarget2D(TextureGlSingle texture, RenderbufferInternalFormat?renderBufferType = null)
        {
            Texture = texture;
            this.renderBufferType = renderBufferType;

            viewport = new Rectangle(0, 0, Width, Height);

            // Make sure the texture is generated and allocated to the proper size.
            Texture.SetData(new byte[0]);
            Texture.Upload();

            if (OsuGlControl.CanUseFBO)
            {
                lastFrameBuffer    = currentFrameBuffer;
                currentFrameBuffer = frameBuffer = GL.GenFramebuffer();

                GL.BindFramebuffer(FramebufferTarget.Framebuffer, frameBuffer);

                GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, All.ColorAttachment0, TextureTarget2d.Texture2D, Texture.TextureId, 0);
                OsuGlControl.BindTexture(0);

                if (renderBufferType != null)
                {
                    renderBuffer = GL.GenRenderbuffer();
                    GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, renderBuffer);
                    GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, RenderbufferInternalFormat.DepthComponent16, Width, Height);
                    GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, All.DepthAttachment, RenderbufferTarget.Renderbuffer, renderBuffer);
                    TotalRenderBuffers++;
                }

                currentFrameBuffer = lastFrameBuffer;
                GL.BindFramebuffer(FramebufferTarget.Framebuffer, lastFrameBuffer);
                TotalFrameBuffers++;
            }

            SetCopyRectangle();
        }
Пример #4
0
        public override bool Upload()
        {
            if (ConfigManager.dDisableTextureUploads)
            {
                return(false);
            }

            // We should never run raw OGL calls on another thread than the main thread due to race conditions.
            Debug.Assert(GameBase.MainThread == Thread.CurrentThread);

            if (isDisposed)
            {
                return(false);
            }

            lock (this)
            {
                if (dataToBeUploaded == null)
                {
                    return(false);
                }

                IntPtr   dataPointer;
                GCHandle?h0;

                if (dataToBeUploaded.Length == 0)
                {
                    h0          = null;
                    dataPointer = IntPtr.Zero;
                }
                else
                {
                    h0          = GCHandle.Alloc(dataToBeUploaded, GCHandleType.Pinned);
                    dataPointer = h0.Value.AddrOfPinnedObject();
                }

                try
                {
                    if (levelToBeUploaded > 0)
                    {
                        return(false);
                    }

                    // Do we need to generate a new texture?
                    if (textureId <= 0 || internalWidth < width || internalHeight < height)
                    {
                        GameBase.PerformanceMonitor.ReportCount(CounterType.TextureGen);

                        internalWidth  = width;
                        internalHeight = height;
                        potWidth       = TextureGl.GetPotDimension(width);
                        potHeight      = TextureGl.GetPotDimension(height);

                        // We only need to generate a new texture if we don't have one already. Otherwise just re-use the current one.
                        if (textureId <= 0)
                        {
#if DEBUG
                            ++GameBase.AmountTextures;
#endif

                            int[] textures = new int[1];
                            GL.GenTextures(1, textures);
                            textureId = textures[0];

                            OsuGlControl.BindTexture(textureId);
                            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear);
                            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear);

                            updateWrapMode();
                        }
                        else
                        {
                            OsuGlControl.BindTexture(textureId);
                        }

                        if (potWidth == boundsToBeUploaded.Width && potHeight == boundsToBeUploaded.Height || dataPointer == IntPtr.Zero)
                        {
                            GL.TexImage2D(TextureTarget2d.Texture2D, levelToBeUploaded, TextureComponentCount.Rgba, potWidth, potHeight, 0, formatToBeUploaded, PixelType.UnsignedByte, dataPointer);
                        }
                        else
                        {
                            if (transparentBlack.Length < potWidth * potHeight * 4)
                            {
                                transparentBlack = new byte[potWidth * potHeight * 4]; // Default value is 0, exactly what we need.
                            }
                            GCHandle h1 = GCHandle.Alloc(transparentBlack, GCHandleType.Pinned);
                            GL.TexImage2D(TextureTarget2d.Texture2D, levelToBeUploaded, TextureComponentCount.Rgba, potWidth, potHeight, 0, formatToBeUploaded, PixelType.UnsignedByte, h1.AddrOfPinnedObject());
                            h1.Free();

                            GL.TexSubImage2D(TextureTarget2d.Texture2D, levelToBeUploaded, boundsToBeUploaded.X, boundsToBeUploaded.Y, boundsToBeUploaded.Width, boundsToBeUploaded.Height, formatToBeUploaded, PixelType.UnsignedByte, dataPointer);
                        }
                    }
                    // Just update content of the current texture
                    else if (dataPointer != IntPtr.Zero)
                    {
                        GameBase.PerformanceMonitor.ReportCount(CounterType.TextureUpload);

                        OsuGlControl.BindTexture(textureId);
                        GL.TexSubImage2D(TextureTarget2d.Texture2D, levelToBeUploaded, boundsToBeUploaded.X, boundsToBeUploaded.Y, boundsToBeUploaded.Width, boundsToBeUploaded.Height, formatToBeUploaded, PixelType.UnsignedByte, dataPointer);
                    }

                    return(true);
                }
                finally
                {
                    if (h0.HasValue)
                    {
                        h0.Value.Free();
                    }

                    if (dataToBeUploaded != null)
                    {
                        FreeBuffer(dataToBeUploaded);
                    }

                    dataToBeUploaded = null;
                }
            }
        }