title: OpenGL: Render-to-texture larger than screen size and glViewport
body: <p>I've been working on this issue for a while and it's time to ask the greater community for help. I have read many other StackOverflow questions on this topic and have not yet found a relevant solution.</p>
  
  <p>I have a well established Android OpenGL project that renders to a texture, before it then renders that texture to the screen. This mechanism is fundamental to my application and I have a lot of history and confidence in it. I recently added new functionality to internally take a screenshot of the rendering; that is to say, my application is able to save the rendered texture to a file as well. These images have traditionally been exactly the size of the display.</p>
  
  <p>Now, I want to generate images that are larger than the screen size, so that the screenshots generated reflect the larger image size, but are also scaled to the screen size when displayed on screen. This should be a straightforward and easy process, however, I am getting unexpected results. The resulting screenshot is the correct size, but is empty except for an area the size of the screen. For example, if the rendered texture and resulting screenshot is intended to be 4 times the screen display size (twice the size of the screen for each dimension X and Y), the screenshot image file will be that intended size, but only the upper left quadrant of the image will have been drawn. In this example, here is the <a href="http://i.stack.imgur.com/HBfFk.png" rel="nofollow">resulting generated screenshot</a>. My viewport is 768x887 and the resulting screenshot is correctly 1536x1774 and within the screenshot, the only colored area is 768x887. For our purposes here, my fragment shader <em>for rendering to texture</em> is a test of the coordinate mapping to the screen...</p>
  
  <pre><code>gl_FragColor = vec4(uv.x, 0.0, uv.y, 1.0);  // during render to texture
  </code></pre>
  
  <p>Note that when we draw this same texture to the screen during execution, the full screen is colored consistent with that shader.  Why is only one quadrant of the screenshot filled, instead of the whole thing? And why, when this texture is drawn on screen, does it display only the part that's the size of the screen, rather than the whole thing with the three empty quadrants?</p>
  
  <p>I get the original size of the viewport from <code>GLSurfaceView.Renderer.onSurfaceChanged()</code> and store it into <code>_viewportWidth</code> and <code>_viewportHeight</code>. When I create the frame buffer texture, I traditionally created it directly from <code>_viewportWidth</code> and <code>_viewportHeight</code>. Now, I have, as an example...</p>
  
  <pre><code>float quality = 2f;
  _frameBufferWidth = (int)((float)_viewportWidth * quality);
  _frameBufferHeight = (int)((float)_viewportHeight * quality);
  </code></pre>
  
  <p>... and generate the frame buffer of size <code>_frameBufferWidth</code> by <code>_frameBufferHeight</code>.</p>
  
  <p>I am also calling <code>glViewport()</code> twice. After my first call to <code>glBindframebuffer()</code> to render to the texture and not the screen, and after doing relevant error handling, I call <code>glViewport(0, 0, _frameBufferWidth, _frameBufferHeight)</code>, which passes without error. When I later want to draw this texture to the screen, I make my second <code>glBindframebuffer()</code> call, and immediately after, call <code>glViewport(0, 0, _viewportWidth, _viewportHeight)</code>. The idea is, the original render to texture is going into a <code>_frameBufferWidth</code> by <code>_frameBufferHeight</code> sized image and when we present it on screen, we want a <code>_viewportWidth</code> by <code>_viewportHeight</code> size.</p>
  
  <p>Any ideas what I may be missing? Thanks in advance.</p>
  
  <p><strong>EDIT (March 10, 2016):</strong>
  I just tried <code>quality=0.5f</code> and am getting unusual results. I would prefer to share more images to clarify this scenario, but I'm a new member and am only allowed two. When we draw to the screen with <code>quality=0.5f</code>, the screen is colored properly according to the GLSL code above: the display is identical to the 768x887 upper left quadrant of the screenshot linked above (corresponding to <code>quality=2f</code>). The <code>quality=0.5f</code> <a href="http://i.stack.imgur.com/Svonf.png" rel="nofollow">screenshot that is generated</a>, however, is colored differently from the screen. This screenshot correctly has the intended 384x443 size, but is still being rendered as though it's 768x887 and just cropping out a 384x443 part.</p>
  
  <p>Even though the code suggests otherwise, it seems as though we're always rendering to a <code>_viewportWidth</code> by <code>_viewportHeight</code> area, rather than the intended <code>_frameBufferWidth</code> by <code>_frameBufferHeight</code> area.</p>
  
  <p>I have basically a full screen quad for both rendering passes and am used to that working OK. When I render to the screen, I sample the texture I just rendered to: </p>
  
  <pre><code>gl_FragColor = texture2D(u_sampler, uv);  // during render to screen
  </code></pre>
  
  <p>The <code>u_sampler</code> accesses the texture we rendered to and <code>uv</code> is in [0,1] for both dimensions. So, for the screen to show anything, it must be doing a texture lookup to get its color information. Thus, the bright red and blue shown on the screen must exist in the framebuffer originally, even though it's missing from the correctly sized screenshot.</p>