private void ActivateShaderProgram()
        {
            // Lookup the shader program.
            var shaderProgram = _programCache.GetProgram(VertexShader, PixelShader);

            if (shaderProgram.Program == null)
            {
                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 == null)
            {
                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;
            }

            gl.uniform4f(posFixupLoc, _posFixup[0], _posFixup[1], _posFixup[2], _posFixup[3]);
            GraphicsExtensions.CheckGLError();
        }
Example #2
0
        /// <summary>
        /// Activates the Current Vertex/Pixel shader pair into a program.
        /// </summary>
        private void ActivateShaderProgram()
        {
            // Lookup the shader program.
            ShaderProgram program = programCache.GetProgram(VertexShader, PixelShader);

            if (program.Program == 0)
            {
                return;
            }

            // Set the new program if it has changed.
            if (shaderProgram != program)
            {
                GLDevice.glUseProgram(program.Program);
                shaderProgram = program;
            }

            int 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[0] = 1.0f;
            posFixup[1] = 1.0f;
            posFixup[2] = (63.0f / 64.0f) / Viewport.Width;
            posFixup[3] = -(63.0f / 64.0f) / Viewport.Height;

            // Flip vertically if we have a render target bound (rendering offscreen)
            if (RenderTargetCount > 0)
            {
                posFixup[1] *= -1.0f;
                posFixup[3] *= -1.0f;
            }

            GLDevice.glUniform4fv(
                posFixupLoc,
                1,
                posFixupPtr
                );
        }