コード例 #1
0
 internal virtual void BindRenderbuffer(int renderbuffer)
 {
     GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, renderbuffer);
     GraphicsExtensions.CheckGLError();
 }
コード例 #2
0
 internal override void DeleteFramebuffer(int id)
 {
     GL.Ext.DeleteFramebuffers(1, ref id);
     GraphicsExtensions.CheckGLError();
 }
コード例 #3
0
        private void PlatformResolveRenderTargets()
        {
            if (this._currentRenderTargetCount == 0)
            {
                return;
            }

            var renderTargetBinding = this._currentRenderTargetBindings[0];
            var renderTarget        = renderTargetBinding.RenderTarget as IRenderTarget;

            if (renderTarget.MultiSampleCount > 0 && this.framebufferHelper.SupportsBlitFramebuffer)
            {
                var glResolveFramebuffer = 0;
                if (!this.glResolveFramebuffers.TryGetValue(this._currentRenderTargetBindings, out glResolveFramebuffer))
                {
                    this.framebufferHelper.GenFramebuffer(out glResolveFramebuffer);
                    this.framebufferHelper.BindFramebuffer(glResolveFramebuffer);
                    for (var i = 0; i < this._currentRenderTargetCount; ++i)
                    {
                        this.framebufferHelper.FramebufferTexture2D((int)(FramebufferAttachment.ColorAttachment0 + i), (int)renderTarget.GetFramebufferTarget(renderTargetBinding), renderTarget.GLTexture);
                    }
                    this.glResolveFramebuffers.Add((RenderTargetBinding[])this._currentRenderTargetBindings.Clone(), glResolveFramebuffer);
                }
                else
                {
                    this.framebufferHelper.BindFramebuffer(glResolveFramebuffer);
                }
                // The only fragment operations which affect the resolve are the pixel ownership test, the scissor test, and dithering.
                if (this._lastRasterizerState.ScissorTestEnable)
                {
                    GL.Disable(EnableCap.ScissorTest);
                    GraphicsExtensions.CheckGLError();
                }
                var glFramebuffer = this.glFramebuffers[this._currentRenderTargetBindings];
                this.framebufferHelper.BindReadFramebuffer(glFramebuffer);
                for (var i = 0; i < this._currentRenderTargetCount; ++i)
                {
                    renderTargetBinding = this._currentRenderTargetBindings[i];
                    renderTarget        = renderTargetBinding.RenderTarget as IRenderTarget;
                    this.framebufferHelper.BlitFramebuffer(i, renderTarget.Width, renderTarget.Height);
                }
                if (renderTarget.RenderTargetUsage == RenderTargetUsage.DiscardContents && this.framebufferHelper.SupportsInvalidateFramebuffer)
                {
                    this.framebufferHelper.InvalidateReadFramebuffer();
                }
                if (this._lastRasterizerState.ScissorTestEnable)
                {
                    GL.Enable(EnableCap.ScissorTest);
                    GraphicsExtensions.CheckGLError();
                }
            }
            for (var i = 0; i < this._currentRenderTargetCount; ++i)
            {
                renderTargetBinding = this._currentRenderTargetBindings[i];
                renderTarget        = renderTargetBinding.RenderTarget as IRenderTarget;
                if (renderTarget.LevelCount > 1)
                {
                    GL.BindTexture((TextureTarget)renderTarget.GLTarget, renderTarget.GLTexture);
                    GraphicsExtensions.CheckGLError();
                    this.framebufferHelper.GenerateMipmap((int)renderTarget.GLTarget);
                }
            }
        }
コード例 #4
0
        internal void PlatformApplyState(bool applyShaders)
        {
            if (_scissorRectangleDirty)
            {
                var scissorRect = _scissorRectangle;
                if (!IsRenderTargetBound)
                {
                    scissorRect.Y = _viewport.Height - scissorRect.Y - scissorRect.Height;
                }
                GL.Scissor(scissorRect.X, scissorRect.Y, scissorRect.Width, scissorRect.Height);
                GraphicsExtensions.CheckGLError();
                _scissorRectangleDirty = false;
            }

            // If we're not applying shaders then early out now.
            if (!applyShaders)
            {
                return;
            }

            if (_indexBufferDirty)
            {
                if (_indexBuffer != null)
                {
                    GL.BindBuffer(BufferTarget.ElementArrayBuffer, _indexBuffer.ibo);
                    GraphicsExtensions.CheckGLError();
                }
                _indexBufferDirty = false;
            }

            if (_vertexBuffersDirty)
            {
                if (_vertexBuffers.Count > 0)
                {
                    GL.BindBuffer(BufferTarget.ArrayBuffer, _vertexBuffers.Get(0).VertexBuffer.vbo);
                    GraphicsExtensions.CheckGLError();
                }
                _vertexBuffersDirty = false;
            }

            if (_vertexShader == null)
            {
                throw new InvalidOperationException("A vertex shader must be set!");
            }
            if (_pixelShader == null)
            {
                throw new InvalidOperationException("A pixel shader must be set!");
            }

            if (_vertexShaderDirty || _pixelShaderDirty)
            {
                ActivateShaderProgram();

                if (_vertexShaderDirty)
                {
                    unchecked
                    {
                        _graphicsMetrics._vertexShaderCount++;
                    }
                }

                if (_pixelShaderDirty)
                {
                    unchecked
                    {
                        _graphicsMetrics._pixelShaderCount++;
                    }
                }

                _vertexShaderDirty = _pixelShaderDirty = false;
            }

            _vertexConstantBuffers.SetConstantBuffers(this, _shaderProgram);
            _pixelConstantBuffers.SetConstantBuffers(this, _shaderProgram);

            Textures.SetTextures(this);
            SamplerStates.PlatformSetSamplers(this);
        }
コード例 #5
0
        private void PlatformSetData <T>(int level, int arraySlice, Rectangle?rect, T[] data, int startIndex, int elementCount) where T : struct
        {
            Threading.BlockOnUIThread(() =>
            {
                var elementSizeInByte = Marshal.SizeOf(typeof(T));
                var dataHandle        = GCHandle.Alloc(data, GCHandleType.Pinned);
                // Use try..finally to make sure dataHandle is freed in case of an error
                try
                {
                    var startBytes = startIndex * elementSizeInByte;
                    var dataPtr    = (IntPtr)(dataHandle.AddrOfPinnedObject().ToInt64() + startBytes);
                    int x, y, w, h;
                    if (rect.HasValue)
                    {
                        x = rect.Value.X;
                        y = rect.Value.Y;
                        w = rect.Value.Width;
                        h = rect.Value.Height;
                    }
                    else
                    {
                        x = 0;
                        y = 0;
                        w = Math.Max(width >> level, 1);
                        h = Math.Max(height >> level, 1);

                        // For DXT textures the width and height of each level is a multiple of 4.
                        // OpenGL only: The last two mip levels require the width and height to be
                        // passed as 2x2 and 1x1, but there needs to be enough data passed to occupy
                        // a 4x4 block.
                        // Ref: http://www.mentby.com/Group/mac-opengl/issue-with-dxt-mipmapped-textures.html
                        if (_format == SurfaceFormat.Dxt1 ||
                            _format == SurfaceFormat.Dxt1a ||
                            _format == SurfaceFormat.Dxt3 ||
                            _format == SurfaceFormat.Dxt5 ||
                            _format == SurfaceFormat.RgbaAtcExplicitAlpha ||
                            _format == SurfaceFormat.RgbaAtcInterpolatedAlpha ||
                            _format == SurfaceFormat.RgbPvrtc2Bpp ||
                            _format == SurfaceFormat.RgbPvrtc4Bpp ||
                            _format == SurfaceFormat.RgbaPvrtc2Bpp ||
                            _format == SurfaceFormat.RgbaPvrtc4Bpp ||
                            _format == SurfaceFormat.RgbEtc1
                            )
                        {
                            if (w > 4)
                            {
                                w = (w + 3) & ~3;
                            }
                            if (h > 4)
                            {
                                h = (h + 3) & ~3;
                            }
                        }
                    }

                    // Store the current bound texture.
                    var prevTexture = GraphicsExtensions.GetBoundTexture2D();

                    GenerateGLTextureIfRequired();

                    GL.BindTexture(TextureTarget.Texture2D, this.glTexture);
                    GraphicsExtensions.CheckGLError();
                    if (glFormat == (PixelFormat)GLPixelFormat.CompressedTextureFormats)
                    {
                        if (rect.HasValue)
                        {
                            GL.CompressedTexSubImage2D(TextureTarget.Texture2D, level, x, y, w, h, glFormat, elementCount - startBytes, dataPtr);
                            GraphicsExtensions.CheckGLError();
                        }
                        else
                        {
                            GL.CompressedTexImage2D(TextureTarget.Texture2D, level, glInternalFormat, w, h, 0, elementCount - startBytes, dataPtr);
                            GraphicsExtensions.CheckGLError();
                        }
                    }
                    else
                    {
                        // Set pixel alignment to match texel size in bytes
                        GL.PixelStore(PixelStoreParameter.UnpackAlignment, GraphicsExtensions.GetSize(this.Format));
                        if (rect.HasValue)
                        {
                            GL.TexSubImage2D(TextureTarget.Texture2D, level,
                                             x, y, w, h,
                                             glFormat, glType, dataPtr);
                            GraphicsExtensions.CheckGLError();
                        }
                        else
                        {
                            GL.TexImage2D(TextureTarget.Texture2D, level,
                                          glInternalFormat,
                                          w, h, 0, glFormat, glType, dataPtr);
                            GraphicsExtensions.CheckGLError();
                        }
                        // Return to default pixel alignment
                        GL.PixelStore(PixelStoreParameter.UnpackAlignment, 4);
                    }

#if !ANDROID
                    GL.Finish();
                    GraphicsExtensions.CheckGLError();
#endif
                    // Restore the bound texture.
                    GL.BindTexture(TextureTarget.Texture2D, prevTexture);
                    GraphicsExtensions.CheckGLError();
                }
                finally
                {
                    dataHandle.Free();
                }

#if !ANDROID
                // Required to make sure that any texture uploads on a thread are completed
                // before the main thread tries to use the texture.
                GL.Finish();
#endif
            });
        }
コード例 #6
0
        private void PlatformConstruct(int width, int height, bool mipmap, SurfaceFormat format, SurfaceType type, bool shared)
        {
            this.glTarget = TextureTarget.Texture2D;

            Threading.BlockOnUIThread(() =>
            {
                // Store the current bound texture.
                var prevTexture = GraphicsExtensions.GetBoundTexture2D();

                GenerateGLTextureIfRequired();

                format.GetGLFormat(GraphicsDevice, out glInternalFormat, out glFormat, out glType);

                if (glFormat == (PixelFormat)GLPixelFormat.CompressedTextureFormats)
                {
                    var imageSize = 0;
                    switch (format)
                    {
                    case SurfaceFormat.RgbPvrtc2Bpp:
                    case SurfaceFormat.RgbaPvrtc2Bpp:
                        imageSize = (Math.Max(this.width, 16) * Math.Max(this.height, 8) * 2 + 7) / 8;
                        break;

                    case SurfaceFormat.RgbPvrtc4Bpp:
                    case SurfaceFormat.RgbaPvrtc4Bpp:
                        imageSize = (Math.Max(this.width, 8) * Math.Max(this.height, 8) * 4 + 7) / 8;
                        break;

                    case SurfaceFormat.Dxt1:
                    case SurfaceFormat.Dxt1a:
                    case SurfaceFormat.Dxt1SRgb:
                    case SurfaceFormat.Dxt3:
                    case SurfaceFormat.Dxt3SRgb:
                    case SurfaceFormat.Dxt5:
                    case SurfaceFormat.Dxt5SRgb:
                    case SurfaceFormat.RgbEtc1:
                    case SurfaceFormat.RgbaAtcExplicitAlpha:
                    case SurfaceFormat.RgbaAtcInterpolatedAlpha:
                        imageSize = ((this.width + 3) / 4) * ((this.height + 3) / 4) * GraphicsExtensions.GetSize(format);
                        break;

                    default:
                        throw new NotSupportedException();
                    }

                    GL.CompressedTexImage2D(TextureTarget.Texture2D, 0, glInternalFormat,
                                            this.width, this.height, 0,
                                            imageSize, IntPtr.Zero);
                    GraphicsExtensions.CheckGLError();
                }
                else
                {
                    GL.TexImage2D(TextureTarget.Texture2D, 0, glInternalFormat,
                                  this.width, this.height, 0,
                                  glFormat, glType, IntPtr.Zero);
                    GraphicsExtensions.CheckGLError();
                }

                // Restore the bound texture.
                GL.BindTexture(TextureTarget.Texture2D, prevTexture);
                GraphicsExtensions.CheckGLError();
            });
        }
コード例 #7
0
 internal virtual void GenerateMipmap(int target)
 {
     GL.GenerateMipmap((TextureTarget)target);
     GraphicsExtensions.CheckGLError();
 }
コード例 #8
0
 internal override void GenerateMipmap(int target)
 {
     GL.Ext.GenerateMipmap((GenerateMipmapTarget)target);
     GraphicsExtensions.CheckGLError();
 }
コード例 #9
0
 internal virtual void DeleteFramebuffer(int framebuffer)
 {
     GL.DeleteFramebuffers(1, ref framebuffer);
     GraphicsExtensions.CheckGLError();
 }
コード例 #10
0
 internal virtual void FramebufferRenderbuffer(int attachement, int renderbuffer, int level = 0)
 {
     GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, (FramebufferSlot)attachement, RenderbufferTarget.Renderbuffer, renderbuffer);
     GraphicsExtensions.CheckGLError();
 }
コード例 #11
0
 internal virtual void BindReadFramebuffer(int readFramebuffer)
 {
     GL.BindFramebuffer((FramebufferTarget)AllReadFramebuffer, readFramebuffer);
     GraphicsExtensions.CheckGLError();
 }
コード例 #12
0
 internal virtual void BindFramebuffer(int framebuffer)
 {
     GL.BindFramebuffer(FramebufferTarget.Framebuffer, framebuffer);
     GraphicsExtensions.CheckGLError();
 }
コード例 #13
0
 internal virtual void DeleteRenderbuffer(int renderbuffer)
 {
     GL.DeleteRenderbuffers(1, ref renderbuffer);
     GraphicsExtensions.CheckGLError();
 }
コード例 #14
0
 internal override void FramebufferTexture2D(int attachement, int target, int texture, int level = 0, int samples = 0)
 {
     GL.Ext.FramebufferTexture2D(FramebufferTarget.FramebufferExt, (FramebufferAttachment)attachement, (TextureTarget)target, texture, level);
     GraphicsExtensions.CheckGLError();
 }
コード例 #15
0
 internal virtual void BlitFramebuffer(int iColorAttachment, int width, int height)
 {
     this.GLBlitFramebuffer(0, 0, width, height, 0, 0, width, height, ClearBufferMask.ColorBufferBit, TextureMagFilter.Nearest);
     GraphicsExtensions.CheckGLError();
 }
コード例 #16
0
 internal override void FramebufferRenderbuffer(int attachement, int renderbuffer, int level = 0)
 {
     GL.Ext.FramebufferRenderbuffer(FramebufferTarget.FramebufferExt, (FramebufferAttachment)attachement, RenderbufferTarget.Renderbuffer, renderbuffer);
     GraphicsExtensions.CheckGLError();
 }
コード例 #17
0
 internal override void BindRenderbuffer(int id)
 {
     GL.Ext.BindRenderbuffer(RenderbufferTarget.RenderbufferExt, id);
     GraphicsExtensions.CheckGLError();
 }
コード例 #18
0
        internal void PlatformApplyState(GraphicsDevice device, bool force = false)
        {
            // When rendering offscreen the faces change order.
            var offscreen = device.IsRenderTargetBound;

            if (force)
            {
                // Turn off dithering to make sure data returned by Texture.GetData is accurate
                GL.Disable(EnableCap.Dither);
            }

            if (CullMode == CullMode.None)
            {
                GL.Disable(EnableCap.CullFace);
                GraphicsExtensions.CheckGLError();
            }
            else
            {
                GL.Enable(EnableCap.CullFace);
                GraphicsExtensions.CheckGLError();
                GL.CullFace(CullFaceMode.Back);
                GraphicsExtensions.CheckGLError();

                if (CullMode == CullMode.CullClockwiseFace)
                {
                    if (offscreen)
                    {
                        GL.FrontFace(FrontFaceDirection.Cw);
                    }
                    else
                    {
                        GL.FrontFace(FrontFaceDirection.Ccw);
                    }
                    GraphicsExtensions.CheckGLError();
                }
                else
                {
                    if (offscreen)
                    {
                        GL.FrontFace(FrontFaceDirection.Ccw);
                    }
                    else
                    {
                        GL.FrontFace(FrontFaceDirection.Cw);
                    }
                    GraphicsExtensions.CheckGLError();
                }
            }

#if MONOMAC || WINDOWS || DESKTOPGL
            if (FillMode == FillMode.Solid)
            {
                GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
            }
            else
            {
                GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
            }
#else
            if (FillMode != FillMode.Solid)
            {
                throw new NotImplementedException();
            }
#endif

            if (force || this.ScissorTestEnable != device._lastRasterizerState.ScissorTestEnable)
            {
                if (ScissorTestEnable)
                {
                    GL.Enable(EnableCap.ScissorTest);
                }
                else
                {
                    GL.Disable(EnableCap.ScissorTest);
                }
                GraphicsExtensions.CheckGLError();
                device._lastRasterizerState.ScissorTestEnable = this.ScissorTestEnable;
            }

            if (force ||
                this.DepthBias != device._lastRasterizerState.DepthBias ||
                this.SlopeScaleDepthBias != device._lastRasterizerState.SlopeScaleDepthBias)
            {
                if (this.DepthBias != 0 || this.SlopeScaleDepthBias != 0)
                {
                    GL.Enable(EnableCap.PolygonOffsetFill);
                    GL.PolygonOffset(this.SlopeScaleDepthBias, this.DepthBias);
                }
                else
                {
                    GL.Disable(EnableCap.PolygonOffsetFill);
                }
                GraphicsExtensions.CheckGLError();
                device._lastRasterizerState.DepthBias           = this.DepthBias;
                device._lastRasterizerState.SlopeScaleDepthBias = this.SlopeScaleDepthBias;
            }

            if (device.GraphicsCapabilities.SupportsDepthClamp &&
                (force || this.DepthClipEnable != device._lastRasterizerState.DepthClipEnable))
            {
                if (!DepthClipEnable)
                {
                    GL.Enable((EnableCap)0x864F);                        // should be EnableCap.DepthClamp, but not available in OpenTK.Graphics.ES20.EnableCap
                }
                else
                {
                    GL.Disable((EnableCap)0x864F);
                }
                GraphicsExtensions.CheckGLError();
                device._lastRasterizerState.DepthClipEnable = this.DepthClipEnable;
            }

            // TODO: Implement MultiSampleAntiAlias
        }
コード例 #19
0
 internal override void RenderbufferStorageMultisample(int samples, int internalFormat, int width, int height)
 {
     GL.Ext.RenderbufferStorageMultisample(RenderbufferTarget.RenderbufferExt, samples, (RenderbufferStorage)internalFormat, width, height);
     GraphicsExtensions.CheckGLError();
 }
コード例 #20
0
        private void PlatformGetData <T>(int level, int arraySlice, Rectangle?rect, T[] data, int startIndex, int elementCount) where T : struct
        {
#if GLES
            // TODO: check for data size and for non renderable formats (formats that can't be attached to FBO)

            var framebufferId = 0;
#if (IOS || ANDROID)
            GL.GenFramebuffers(1, out framebufferId);
#else
            GL.GenFramebuffers(1, ref framebufferId);
#endif
            GraphicsExtensions.CheckGLError();
            GL.BindFramebuffer(FramebufferTarget.Framebuffer, framebufferId);
            GraphicsExtensions.CheckGLError();
            GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferSlot.ColorAttachment0, TextureTarget.Texture2D, this.glTexture, 0);
            GraphicsExtensions.CheckGLError();
            var x      = 0;
            var y      = 0;
            var width  = this.width;
            var height = this.height;
            if (rect.HasValue)
            {
                x      = rect.Value.X;
                y      = rect.Value.Y;
                width  = this.Width;
                height = this.Height;
            }
            GL.ReadPixels(x, y, width, height, this.glFormat, this.glType, data);
            GraphicsExtensions.CheckGLError();
            GL.DeleteFramebuffers(1, ref framebufferId);
            GraphicsExtensions.CheckGLError();
#else
            GL.BindTexture(TextureTarget.Texture2D, this.glTexture);

            if (glFormat == (PixelFormat)GLPixelFormat.CompressedTextureFormats)
            {
                throw new NotImplementedException();
            }
            else
            {
                if (rect.HasValue)
                {
                    var temp = new T[this.width * this.height];
                    GL.GetTexImage(TextureTarget.Texture2D, level, this.glFormat, this.glType, temp);
                    int z = 0, w = 0;

                    for (int y = rect.Value.Y; y < rect.Value.Y + rect.Value.Height; ++y)
                    {
                        for (int x = rect.Value.X; x < rect.Value.X + rect.Value.Width; ++x)
                        {
                            data[z * rect.Value.Width + w] = temp[(y * width) + x];
                            ++w;
                        }
                        ++z;
                        w = 0;
                    }
                }
                else
                {
                    GL.GetTexImage(TextureTarget.Texture2D, level, this.glFormat, this.glType, data);
                }
            }
#endif
        }
コード例 #21
0
 internal override void GenFramebuffer(out int id)
 {
     GL.Ext.GenFramebuffers(1, out id);
     GraphicsExtensions.CheckGLError();
 }
コード例 #22
0
        public void PlatformClear(ClearOptions options, Vector4 color, float depth, int stencil)
        {
            // TODO: We need to figure out how to detect if we have a
            // depth stencil buffer or not, and clear options relating
            // to them if not attached.

            // Unlike with XNA and DirectX...  GL.Clear() obeys several
            // different render states:
            //
            //  - The color write flags.
            //  - The scissor rectangle.
            //  - The depth/stencil state.
            //
            // So overwrite these states with what is needed to perform
            // the clear correctly and restore it afterwards.
            //
            var prevScissorRect       = ScissorRectangle;
            var prevDepthStencilState = DepthStencilState;
            var prevBlendState        = BlendState;

            ScissorRectangle = _viewport.Bounds;
            // DepthStencilState.Default has the Stencil Test disabled;
            // make sure stencil test is enabled before we clear since
            // some drivers won't clear with stencil test disabled
            DepthStencilState = this.clearDepthStencilState;
            BlendState        = BlendState.Opaque;
            ApplyState(false);

            ClearBufferMask bufferMask = 0;

            if ((options & ClearOptions.Target) == ClearOptions.Target)
            {
                if (color != _lastClearColor)
                {
                    GL.ClearColor(color.X, color.Y, color.Z, color.W);
                    GraphicsExtensions.CheckGLError();
                    _lastClearColor = color;
                }
                bufferMask = bufferMask | ClearBufferMask.ColorBufferBit;
            }
            if ((options & ClearOptions.Stencil) == ClearOptions.Stencil)
            {
                if (stencil != _lastClearStencil)
                {
                    GL.ClearStencil(stencil);
                    GraphicsExtensions.CheckGLError();
                    _lastClearStencil = stencil;
                }
                bufferMask = bufferMask | ClearBufferMask.StencilBufferBit;
            }

            if ((options & ClearOptions.DepthBuffer) == ClearOptions.DepthBuffer)
            {
                if (depth != _lastClearDepth)
                {
#if GLES
                    GL.ClearDepth(depth);
#else
                    GL.ClearDepth(depth);
#endif
                    GraphicsExtensions.CheckGLError();
                    _lastClearDepth = depth;
                }
                bufferMask = bufferMask | ClearBufferMask.DepthBufferBit;
            }

            GL.Clear(bufferMask);
            GraphicsExtensions.CheckGLError();

            // Restore the previous render state.
            ScissorRectangle  = prevScissorRect;
            DepthStencilState = prevDepthStencilState;
            BlendState        = prevBlendState;
        }
コード例 #23
0
 internal override void BindFramebuffer(int id)
 {
     GL.Ext.BindFramebuffer(FramebufferTarget.Framebuffer, id);
     GraphicsExtensions.CheckGLError();
 }
コード例 #24
0
        /// <summary>
        /// Activates the Current Vertex/Pixel shader pair into a program.
        /// </summary>
        private unsafe void ActivateShaderProgram()
        {
            // Lookup the shader program.
            var shaderProgram = _programCache.GetProgram(VertexShader, PixelShader);

            if (shaderProgram.Program == -1)
            {
                return;
            }
            // Set the new program if it has changed.
            if (_shaderProgram != shaderProgram)
            {
                GL.UseProgram(shaderProgram.Program);
                GraphicsExtensions.CheckGLError();
                _shaderProgram = shaderProgram;
            }

            var posFixupLoc = shaderProgram.GetUniformLocation("posFixup");

            if (posFixupLoc == -1)
            {
                return;
            }

            // Apply vertex shader fix:
            // The following two lines are appended to the end of vertex shaders
            // to account for rendering differences between OpenGL and DirectX:
            //
            // gl_Position.y = gl_Position.y * posFixup.y;
            // gl_Position.xy += posFixup.zw * gl_Position.ww;
            //
            // (the following paraphrased from wine, wined3d/state.c and wined3d/glsl_shader.c)
            //
            // - We need to flip along the y-axis in case of offscreen rendering.
            // - D3D coordinates refer to pixel centers while GL coordinates refer
            //   to pixel corners.
            // - D3D has a top-left filling convention. We need to maintain this
            //   even after the y-flip mentioned above.
            // In order to handle the last two points, we translate by
            // (63.0 / 128.0) / VPw and (63.0 / 128.0) / VPh. This is equivalent to
            // translating slightly less than half a pixel. We want the difference to
            // be large enough that it doesn't get lost due to rounding inside the
            // driver, but small enough to prevent it from interfering with any
            // anti-aliasing.
            //
            // OpenGL coordinates specify the center of the pixel while d3d coords specify
            // the corner. The offsets are stored in z and w in posFixup. posFixup.y contains
            // 1.0 or -1.0 to turn the rendering upside down for offscreen rendering. PosFixup.x
            // contains 1.0 to allow a mad.

            _posFixup[0] = 1.0f;
            _posFixup[1] = 1.0f;
            _posFixup[2] = (63.0f / 64.0f) / Viewport.Width;
            _posFixup[3] = -(63.0f / 64.0f) / Viewport.Height;

            //If we have a render target bound (rendering offscreen)
            if (IsRenderTargetBound)
            {
                //flip vertically
                _posFixup[1] *= -1.0f;
                _posFixup[3] *= -1.0f;
            }

            fixed(float *floatPtr = _posFixup)
            {
                GL.Uniform4(posFixupLoc, 1, floatPtr);
            }

            GraphicsExtensions.CheckGLError();
        }
コード例 #25
0
 internal override void BindReadFramebuffer(int readFramebuffer)
 {
     GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, readFramebuffer);
     GraphicsExtensions.CheckGLError();
 }
コード例 #26
0
        private void PlatformSetup()
        {
#if DESKTOPGL || ANGLE
            var windowInfo = new WindowInfo(SdlGameWindow.Instance.Handle);

            if (Context == null || Context.IsDisposed)
            {
                Context = GL.CreateContext(windowInfo);
            }

            Context.MakeCurrent(windowInfo);
            Context.SwapInterval = PresentationParameters.PresentationInterval.GetSwapInterval();

            /*if (Threading.BackgroundContext == null)
             * {
             *       Threading.BackgroundContext = GL.CreateContext(windowInfo);
             *       Threading.WindowInfo = windowInfo;
             *       Threading.BackgroundContext.MakeCurrent(null);
             * }*/

            Context.MakeCurrent(windowInfo);

            /*GraphicsMode mode = GraphicsMode.Default;
             * var wnd = OpenTK.Platform.Utilities.CreateSdl2WindowInfo(Game.Instance.Window.Handle);
             *
             #if GLES
             * // Create an OpenGL ES 2.0 context
             * var flags = GraphicsContextFlags.Embedded;
             * int major = 2;
             * int minor = 0;
             #else
             * // Create an OpenGL compatibility context
             * var flags = GraphicsContextFlags.Default;
             * int major = 1;
             * int minor = 0;
             #endif
             *
             * if (Context == null || Context.IsDisposed)
             * {
             *       var color = PresentationParameters.BackBufferFormat.GetColorFormat();
             *       var depth =
             *                PresentationParameters.DepthStencilFormat == DepthFormat.None ? 0 :
             *                PresentationParameters.DepthStencilFormat == DepthFormat.Depth16 ? 16 :
             *                24;
             *       var stencil =
             *                PresentationParameters.DepthStencilFormat == DepthFormat.Depth24Stencil8 ? 8 :
             *                0;
             *
             *       var samples = 0;
             *       if (Game.Instance.graphicsDeviceManager.PreferMultiSampling)
             *       {
             *                // Use a default of 4x samples if PreferMultiSampling is enabled
             *                // without explicitly setting the desired MultiSampleCount.
             *                if (PresentationParameters.MultiSampleCount == 0)
             *                {
             *                              PresentationParameters.MultiSampleCount = 4;
             *                }
             *
             *                samples = PresentationParameters.MultiSampleCount;
             *       }
             *
             *       mode = new GraphicsMode(color, depth, stencil, samples);
             *       try
             *       {
             *                Context = new GraphicsContext(mode, wnd, major, minor, flags);
             *       }
             *       catch (Exception e)
             *       {
             *                Game.Instance.Log("Failed to create OpenGL context, retrying. Error: " +
             *                              e.ToString());
             *                major = 1;
             *                minor = 0;
             *                flags = GraphicsContextFlags.Default;
             *                Context = new GraphicsContext(mode, wnd, major, minor, flags);
             *       }
             * }
             * Context.MakeCurrent(wnd);
             * (Context as IGraphicsContextInternal).LoadAll();
             * Context.SwapInterval = PresentationParameters.PresentationInterval.GetSwapInterval();
             *
             * // Provide the graphics context for background loading
             * // Note: this context should use the same GraphicsMode,
             * // major, minor version and flags parameters as the main
             * // context. Otherwise, context sharing will very likely fail.
             * if (Threading.BackgroundContext == null)
             * {
             *       Threading.BackgroundContext = new GraphicsContext(mode, wnd, major, minor, flags);
             *       Threading.WindowInfo = wnd;
             *       Threading.BackgroundContext.MakeCurrent(null);
             * }
             * Context.MakeCurrent(wnd);*/
#endif

            MaxTextureSlots = 16;

            GL.GetInteger(GetPName.MaxTextureImageUnits, out MaxTextureSlots);
            GraphicsExtensions.CheckGLError();

            GL.GetInteger(GetPName.MaxVertexAttribs, out MaxVertexAttributes);
            GraphicsExtensions.CheckGLError();

            GL.GetInteger(GetPName.MaxTextureSize, out _maxTextureSize);
            GraphicsExtensions.CheckGLError();

            SpriteBatch.NeedsHalfPixelOffset = true;

            // try getting the context version
            // GL_MAJOR_VERSION and GL_MINOR_VERSION are GL 3.0+ only, so we need to rely on the GL_VERSION string
            // for non GLES this string always starts with the version number in the "major.minor" format, but can be followed by
            // multiple vendor specific characters
            // For GLES this string is formatted as: OpenGL<space>ES<space><version number><space><vendor-specific information>
#if GLES
            try
            {
                string   version      = GL.GetString(StringName.Version);
                string[] versionSplit = version.Split(' ');
                if (versionSplit.Length > 2 && versionSplit[0].Equals("OpenGL") && versionSplit[1].Equals("ES"))
                {
                    glMajorVersion = Convert.ToInt32(versionSplit[2].Substring(0, 1));
                    glMinorVersion = Convert.ToInt32(versionSplit[2].Substring(2, 1));
                }
                else
                {
                    glMajorVersion = 1;
                    glMinorVersion = 1;
                }
            }
            catch (FormatException)
            {
                //if it fails we default to 1.1 context
                glMajorVersion = 1;
                glMinorVersion = 1;
            }
#else
            try
            {
                string version = GL.GetString(StringName.Version);
                glMajorVersion = Convert.ToInt32(version.Substring(0, 1));
                glMinorVersion = Convert.ToInt32(version.Substring(2, 1));
            }
            catch (FormatException)
            {
                // if it fails, we assume to be on a 1.1 context
                glMajorVersion = 1;
                glMinorVersion = 1;
            }
#endif

#if !GLES
            // Initialize draw buffer attachment array
            int maxDrawBuffers;
            GL.GetInteger(GetPName.MaxDrawBuffers, out maxDrawBuffers);
            GraphicsExtensions.CheckGLError();
            _drawBuffers = new DrawBuffersEnum[maxDrawBuffers];
            for (int i = 0; i < maxDrawBuffers; i++)
            {
                _drawBuffers[i] = (DrawBuffersEnum)(FramebufferAttachment.ColorAttachment0Ext + i);
            }
#endif
            _extensions = GetGLExtensions();
        }
コード例 #27
0
        internal void PlatformApplyState(GraphicsDevice device, bool force = false)
        {
            var blendEnabled = !(this.ColorSourceBlend == Blend.One &&
                                 this.ColorDestinationBlend == Blend.Zero &&
                                 this.AlphaSourceBlend == Blend.One &&
                                 this.AlphaDestinationBlend == Blend.Zero);

            if (force || blendEnabled != device._lastBlendEnable)
            {
                if (blendEnabled)
                {
                    GL.Enable(EnableCap.Blend);
                }
                else
                {
                    GL.Disable(EnableCap.Blend);
                }
                GraphicsExtensions.CheckGLError();
                device._lastBlendEnable = blendEnabled;
            }

            if (force || this.BlendFactor != device._lastBlendState.BlendFactor)
            {
                GL.BlendColor(
                    this.BlendFactor.R / 255.0f,
                    this.BlendFactor.G / 255.0f,
                    this.BlendFactor.B / 255.0f,
                    this.BlendFactor.A / 255.0f);
                GraphicsExtensions.CheckGLError();
                device._lastBlendState.BlendFactor = this.BlendFactor;
            }

            if (force ||
                this.ColorBlendFunction != device._lastBlendState.ColorBlendFunction ||
                this.AlphaBlendFunction != device._lastBlendState.AlphaBlendFunction)
            {
                GL.BlendEquationSeparate(
                    this.ColorBlendFunction.GetBlendEquationMode(),
                    this.AlphaBlendFunction.GetBlendEquationMode());
                GraphicsExtensions.CheckGLError();
                device._lastBlendState.ColorBlendFunction = this.ColorBlendFunction;
                device._lastBlendState.AlphaBlendFunction = this.AlphaBlendFunction;
            }

            if (force ||
                this.ColorSourceBlend != device._lastBlendState.ColorSourceBlend ||
                this.ColorDestinationBlend != device._lastBlendState.ColorDestinationBlend ||
                this.AlphaSourceBlend != device._lastBlendState.AlphaSourceBlend ||
                this.AlphaDestinationBlend != device._lastBlendState.AlphaDestinationBlend)
            {
                GL.BlendFuncSeparate(
                    this.ColorSourceBlend.GetBlendFactorSrc(),
                    this.ColorDestinationBlend.GetBlendFactorDest(),
                    this.AlphaSourceBlend.GetBlendFactorSrc(),
                    this.AlphaDestinationBlend.GetBlendFactorDest());
                GraphicsExtensions.CheckGLError();
                device._lastBlendState.ColorSourceBlend      = this.ColorSourceBlend;
                device._lastBlendState.ColorDestinationBlend = this.ColorDestinationBlend;
                device._lastBlendState.AlphaSourceBlend      = this.AlphaSourceBlend;
                device._lastBlendState.AlphaDestinationBlend = this.AlphaDestinationBlend;
            }

            if (force || this.ColorWriteChannels != device._lastBlendState.ColorWriteChannels)
            {
                GL.ColorMask(
                    (this.ColorWriteChannels & ColorWriteChannels.Red) != 0,
                    (this.ColorWriteChannels & ColorWriteChannels.Green) != 0,
                    (this.ColorWriteChannels & ColorWriteChannels.Blue) != 0,
                    (this.ColorWriteChannels & ColorWriteChannels.Alpha) != 0);
                GraphicsExtensions.CheckGLError();
                device._lastBlendState.ColorWriteChannels = this.ColorWriteChannels;
            }
        }