/// <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 ); }