Added st_fb_orientation() function to determine the up/down orientation of the frameb...
authorBrian <brian.paul@tungstengraphics.com>
Tue, 14 Aug 2007 00:16:11 +0000 (18:16 -0600)
committerBrian <brian.paul@tungstengraphics.com>
Tue, 14 Aug 2007 00:20:04 +0000 (18:20 -0600)
src/mesa/state_tracker/st_atom_viewport.c
src/mesa/state_tracker/st_cb_readpixels.c
src/mesa/state_tracker/st_context.h

index 1307cbb6d2a430994f342d1a418cf815f7ecb2b5..a70f4c7434e3d89cf9632099d1c8bdb7c791ec3b 100644 (file)
  *  - depthrange
  *  - window pos/size or FBO size
  */
-static void update_viewport( struct st_context *st )
+static void
+update_viewport( struct st_context *st )
 {
    GLcontext *ctx = st->ctx;
    GLfloat yScale, yBias;
 
-   /* Negate Y scale to flip image vertically.
-    * The NDC Y coords prior to viewport transformation are in the range
-    * [y=-1=bottom, y=1=top]
-    * Hardware window coords are in the range [y=0=top, y=H-1=bottom] where H
-    * is the window height.
-    * Use the viewport transformation to invert Y.
-    */
-
    /* _NEW_BUFFERS
     */
-   if (ctx->DrawBuffer) {
+   if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
       yScale = -1;
       yBias = ctx->DrawBuffer->Height ;
    }
    else {
-      /* we won't be rendering anything */
       yScale = 1.0;
       yBias = 0.0;
    }
index 22abc104e22dae0fd343a5229712bc80140e296e..98604e5b6b546f06a15d9133f61570457b0abcf6 100644 (file)
@@ -60,7 +60,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
    struct pipe_context *pipe = ctx->st->pipe;
    GLfloat temp[MAX_WIDTH][4];
    const GLbitfield transferOps = ctx->_ImageTransferState;
-   GLint i, yInv, dfStride;
+   GLint i, yStep, dfStride;
    GLfloat *df;
    struct st_renderbuffer *strb;
    struct gl_pixelstore_attrib clippedPacking = *pack;
@@ -104,11 +104,19 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
       dfStride = 0;
    }
 
+   /* determine bottom-to-top vs. top-to-bottom order */
+   if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
+      y = strb->Base.Height - 1 - y;
+      yStep = -1;
+   }
+   else {
+      yStep = 1;
+   }
+
    /* Do a row at a time to flip image data vertically */
-   yInv = strb->Base.Height - 1 - y;
    for (i = 0; i < height; i++) {
-      strb->surface->get_tile(strb->surface, x, yInv, width, 1, df);
-      yInv--;
+      strb->surface->get_tile(strb->surface, x, y, width, 1, df);
+      y += yStep;
       df += dfStride;
       if (!dfStride) {
          /* convert GLfloat to user's format/type */
index 8d82d53133fa73ae7e10c42fbc884c5dfdf54feb..13843d9b7fe417d11dde7e2402239243b526d837 100644 (file)
@@ -118,5 +118,32 @@ extern void st_init_driver_functions(struct dd_function_table *functions);
 
 
 
+#define Y_0_TOP 1
+#define Y_0_BOTTOM 2
+
+static INLINE GLuint
+st_fb_orientation(const struct gl_framebuffer *fb)
+{
+   if (fb && fb->Name == 0) {
+      /* Drawing into a window (on-screen buffer).
+       *
+       * Negate Y scale to flip image vertically.
+       * The NDC Y coords prior to viewport transformation are in the range
+       * [y=-1=bottom, y=1=top]
+       * Hardware window coords are in the range [y=0=top, y=H-1=bottom] where
+       * H is the window height.
+       * Use the viewport transformation to invert Y.
+       */
+      return Y_0_TOP;
+   }
+   else {
+      /* Drawing into user-created FBO (very likely a texture).
+       *
+       * For textures, T=0=Bottom, so by extension Y=0=Bottom for rendering.
+       */
+      return Y_0_BOTTOM;
+   }
+}
+
 
 #endif