Exemple #1
0
/**
 * Bilinear interpolation of two source rows.
 * GLubyte pixels.
 */
static void
resample_linear_row_ub(GLint srcWidth, GLint dstWidth,
                       const GLvoid *srcBuffer0, const GLvoid *srcBuffer1,
                       GLvoid *dstBuffer, GLboolean flip, GLfloat rowWeight)
{
   const GLubyte (*srcColor0)[4] = (const GLubyte (*)[4]) srcBuffer0;
   const GLubyte (*srcColor1)[4] = (const GLubyte (*)[4]) srcBuffer1;
   GLubyte (*dstColor)[4] = (GLubyte (*)[4]) dstBuffer;
   const GLfloat dstWidthF = (GLfloat) dstWidth;
   GLint dstCol;

   for (dstCol = 0; dstCol < dstWidth; dstCol++) {
      const GLfloat srcCol = (dstCol * srcWidth) / dstWidthF;
      GLint srcCol0 = IFLOOR(srcCol);
      GLint srcCol1 = srcCol0 + 1;
      GLfloat colWeight = srcCol - srcCol0; /* fractional part of srcCol */
      GLfloat red, green, blue, alpha;

      ASSERT(srcCol0 >= 0);
      ASSERT(srcCol0 < srcWidth);
      ASSERT(srcCol1 <= srcWidth);

      if (srcCol1 == srcWidth) {
         /* last column fudge */
         srcCol1--;
         colWeight = 0.0;
      }

      if (flip) {
         srcCol0 = srcWidth - 1 - srcCol0;
         srcCol1 = srcWidth - 1 - srcCol1;
      }

      red = lerp_2d(colWeight, rowWeight,
                    srcColor0[srcCol0][RCOMP], srcColor0[srcCol1][RCOMP],
                    srcColor1[srcCol0][RCOMP], srcColor1[srcCol1][RCOMP]);
      green = lerp_2d(colWeight, rowWeight,
                    srcColor0[srcCol0][GCOMP], srcColor0[srcCol1][GCOMP],
                    srcColor1[srcCol0][GCOMP], srcColor1[srcCol1][GCOMP]);
      blue = lerp_2d(colWeight, rowWeight,
                    srcColor0[srcCol0][BCOMP], srcColor0[srcCol1][BCOMP],
                    srcColor1[srcCol0][BCOMP], srcColor1[srcCol1][BCOMP]);
      alpha = lerp_2d(colWeight, rowWeight,
                    srcColor0[srcCol0][ACOMP], srcColor0[srcCol1][ACOMP],
                    srcColor1[srcCol0][ACOMP], srcColor1[srcCol1][ACOMP]);
      
      dstColor[dstCol][RCOMP] = IFLOOR(red);
      dstColor[dstCol][GCOMP] = IFLOOR(green);
      dstColor[dstCol][BCOMP] = IFLOOR(blue);
      dstColor[dstCol][ACOMP] = IFLOOR(alpha);
   }
}
Exemple #2
0
void
_mesa_Bitmap( GLsizei width, GLsizei height,
              GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove,
              const GLubyte *bitmap )
{
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);

   if (width < 0 || height < 0) {
      _mesa_error( ctx, GL_INVALID_VALUE, "glBitmap(width or height < 0)" );
      return;
   }

   if (ctx->Current.RasterPosValid == GL_FALSE) {
      return;    /* do nothing */
   }

   if (ctx->RenderMode==GL_RENDER) {
      if (bitmap) {
         /* Truncate, to satisfy conformance tests (matches SGI's OpenGL). */
         GLint x = IFLOOR(ctx->Current.RasterPos[0] - xorig);
         GLint y = IFLOOR(ctx->Current.RasterPos[1] - yorig);

         if (ctx->NewState) {
            _mesa_update_state(ctx);
         }

         ctx->OcclusionResult = GL_TRUE;
	 ctx->Driver.Bitmap( ctx, x, y, width, height, &ctx->Unpack, bitmap );
      }
   }
   else if (ctx->RenderMode==GL_FEEDBACK) {
      if (ctx->Current.RasterPosValid) {
	 FLUSH_CURRENT(ctx, 0);
         FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_BITMAP_TOKEN );
         _mesa_feedback_vertex( ctx,
				ctx->Current.RasterPos,
				ctx->Current.RasterColor,
				ctx->Current.RasterIndex, 
				ctx->Current.RasterTexCoord );
      }
   }
   else if (ctx->RenderMode==GL_SELECT) {
      /* Bitmaps don't generate selection hits.  See appendix B of 1.1 spec. */
   }

   /* update raster position */
   ctx->Current.RasterPos[0] += xmove;
   ctx->Current.RasterPos[1] += ymove;
}
Exemple #3
0
/**
 * Bilinear interpolation of two source rows.  floating point pixels.
 */
static void
resample_linear_row_float(GLint srcWidth, GLint dstWidth,
                          const GLvoid *srcBuffer0, const GLvoid *srcBuffer1,
                          GLvoid *dstBuffer, GLboolean flip, GLfloat rowWeight)
{
   const GLfloat (*srcColor0)[4] = (const GLfloat (*)[4]) srcBuffer0;
   const GLfloat (*srcColor1)[4] = (const GLfloat (*)[4]) srcBuffer1;
   GLfloat (*dstColor)[4] = (GLfloat (*)[4]) dstBuffer;
   GLint dstCol;

   for (dstCol = 0; dstCol < dstWidth; dstCol++) {
      const GLfloat srcCol = (dstCol + 0.5F) / dstWidth * srcWidth - 0.5F;
      GLint srcCol0 = MAX2(0, IFLOOR(srcCol));
      GLint srcCol1 = srcCol0 + 1;
      GLfloat colWeight = srcCol - srcCol0; /* fractional part of srcCol */
      GLfloat red, green, blue, alpha;

      assert(srcCol0 < srcWidth);
      assert(srcCol1 <= srcWidth);

      if (srcCol1 == srcWidth) {
         /* last column fudge */
         srcCol1--;
         colWeight = 0.0;
      }

      if (flip) {
         srcCol0 = srcWidth - 1 - srcCol0;
         srcCol1 = srcWidth - 1 - srcCol1;
      }

      red = lerp_2d(colWeight, rowWeight,
                    srcColor0[srcCol0][RCOMP], srcColor0[srcCol1][RCOMP],
                    srcColor1[srcCol0][RCOMP], srcColor1[srcCol1][RCOMP]);
      green = lerp_2d(colWeight, rowWeight,
                    srcColor0[srcCol0][GCOMP], srcColor0[srcCol1][GCOMP],
                    srcColor1[srcCol0][GCOMP], srcColor1[srcCol1][GCOMP]);
      blue = lerp_2d(colWeight, rowWeight,
                    srcColor0[srcCol0][BCOMP], srcColor0[srcCol1][BCOMP],
                    srcColor1[srcCol0][BCOMP], srcColor1[srcCol1][BCOMP]);
      alpha = lerp_2d(colWeight, rowWeight,
                    srcColor0[srcCol0][ACOMP], srcColor0[srcCol1][ACOMP],
                    srcColor1[srcCol0][ACOMP], srcColor1[srcCol1][ACOMP]);
      
      dstColor[dstCol][RCOMP] = red;
      dstColor[dstCol][GCOMP] = green;
      dstColor[dstCol][BCOMP] = blue;
      dstColor[dstCol][ACOMP] = alpha;
   }
}
Exemple #4
0
int
warpRecFromTetPerspRgb (ppf dst, ppf src, int dX, int dY, unt dW, unt dH
	, pDmj sD, float sQ[4][2])
{
float   sx0 = sQ[0][0],  sx1 = sQ[1][0],  sx2 = sQ[2][0],  sx3 = sQ[3][0];
float   sy0 = sQ[0][1],  sy1 = sQ[1][1],  sy2 = sQ[2][1],  sy3 = sQ[3][1];
float	x21 = sx2 - sx1, x32 = sx3 - sx2;
float	y21 = sy2 - sy1, y32 = sy3 - sy2;
float	x44 = sx0 - sx1 + sx2 - sx3;
float	y44 = sy0 - sy1 + sy2 - sy3;
#if 0	/* AFFINE: for SPECIAL CASE OF x44 == 0 && y44 == 0 */
float   x10 = sx1 - sx0,  y10 = sy1 - sy0;
float 	a11 = x10,  a12 = y10,  a13 = 0.0;
float 	a21 = x21,  a22 = y21,  a23 = 0.0;
float 	a31 = sx0,  a32 = sy0,  a33 = 1.0;
#else	/* PERSPECIVE/PROJECTIVE: YES */
float	det = (y21*x32 - x21*y32);
float	a13 = (x44*y32 - y44*x32)/det;
float	a23 = (y21*x44 - x21*y44)/det;
float	a33 = 1.0F;
float	a31 = sx0;
float	a32 = sy0;
float	a11 = (1.0F + a13)*sx1 - a31;
float	a21 = (1.0F + a23)*sx3 - a31;
float	a12 = (1.0F + a13)*sy1 - a32;
float	a22 = (1.0F + a23)*sy3 - a32;
#endif
double 	fx,fy,fw,fh, mx,my,mw,mh, xx, yy, ww, fL,fM,fN,fO;
pfl 	dp, sp;
float 	sWm = sD->w - 1.3333, sHm = sD->h - 1.3333;
int  	k,  j, ks, js, sM  = sD->w * 3, sP = sM + 3;

  for (  j = 0; j < dH; j++) {	/* GO BY HALF-INTEGER INCREMENTS?? @@ */
    fh = (dbl)  j / dH;
    mh = 1.0F - fh;
    dp = dst[j + dY] + dX*3;
    for (k = 0;  k < dW; k++) {
      fw  = (dbl)k / dW;
      mw  = 1.0F - fw;
      ww  = (a13*fw + a23*fh + a33);
      xx  = (a11*fw + a21*fh + a31)/ww;
      yy  = (a12*fw + a22*fh + a32)/ww;
      /* if(!(++cnt%711)) printf("wPTB %3d %3d:  % 7.3f % 7.3f  (%7.3f)\n",j,k,xx,yy,ww); */
      if  (xx < 0.0)  xx = 0.3333;  else if (xx >= sWm)  xx = sWm;
      if  (yy < 0.0)  yy = 0.3333;  else if (yy >= sHm)  yy = sHm;
      js    = IFLOOR(yy);  fy = yy - js;  my = 1.0F - fy;
      ks    = IFLOOR(xx);  fx = xx - ks;  mx = 1.0F - fx;
      sp    = src[js] + ks*3;
      fL    = mx*my;
      fM    = fx*my;
      fN    = mx*fy;
      fO    = fx*fy;
      *dp++ = fL*sp[0] + fM*sp[3] + fN*sp[sM] + fO*sp[sP];  sp++;
      *dp++ = fL*sp[0] + fM*sp[3] + fN*sp[sM] + fO*sp[sP];  sp++;
      *dp++ = fL*sp[0] + fM*sp[3] + fN*sp[sM] + fO*sp[sP];
    }
  }
/***********************************************************
printf("warpRecFromTetPerspRgb [a]:\n\
\t% 14.3f\t% 14.3f\t% 14.3f\n", a11, a12, a13); printf("\
\t% 14.3f\t% 14.3f\t% 14.3f\n", a21, a22, a23); printf("\
\t% 14.3f\t% 14.3f\t% 14.3f\n", a31, a32, a33);
************************************************************/
return 0;
}
Exemple #5
0
/**
 * Bilinear filtered blit (color only).
 */
static void
blit_linear(struct gl_context *ctx,
            GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
            GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1)
{
   struct gl_renderbuffer *readRb = ctx->ReadBuffer->_ColorReadBuffer;
   struct gl_renderbuffer *drawRb = ctx->DrawBuffer->_ColorDrawBuffers[0];

   const GLint srcWidth = ABS(srcX1 - srcX0);
   const GLint dstWidth = ABS(dstX1 - dstX0);
   const GLint srcHeight = ABS(srcY1 - srcY0);
   const GLint dstHeight = ABS(dstY1 - dstY0);
   const GLfloat dstHeightF = (GLfloat) dstHeight;

   const GLint srcXpos = MIN2(srcX0, srcX1);
   const GLint srcYpos = MIN2(srcY0, srcY1);
   const GLint dstXpos = MIN2(dstX0, dstX1);
   const GLint dstYpos = MIN2(dstY0, dstY1);

   const GLboolean invertX = (srcX1 < srcX0) ^ (dstX1 < dstX0);
   const GLboolean invertY = (srcY1 < srcY0) ^ (dstY1 < dstY0);

   GLint dstRow;

   GLint pixelSize;
   GLvoid *srcBuffer0, *srcBuffer1;
   GLint srcBufferY0 = -1, srcBufferY1 = -1;
   GLvoid *dstBuffer;

   switch (readRb->DataType) {
   case GL_UNSIGNED_BYTE:
      pixelSize = 4 * sizeof(GLubyte);
      break;
   case GL_UNSIGNED_SHORT:
      pixelSize = 4 * sizeof(GLushort);
      break;
   case GL_UNSIGNED_INT:
      pixelSize = 4 * sizeof(GLuint);
      break;
   case GL_FLOAT:
      pixelSize = 4 * sizeof(GLfloat);
      break;
   default:
      _mesa_problem(ctx, "unexpected buffer type (0x%x) in blit_nearest",
                    readRb->DataType);
      return;
   }

   /* Allocate the src/dst row buffers.
    * Keep two adjacent src rows around for bilinear sampling.
    */
   srcBuffer0 = malloc(pixelSize * srcWidth);
   if (!srcBuffer0) {
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT");
      return;
   }
   srcBuffer1 = malloc(pixelSize * srcWidth);
   if (!srcBuffer1) {
      free(srcBuffer0);
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT");
      return;
   }
   dstBuffer = malloc(pixelSize * dstWidth);
   if (!dstBuffer) {
      free(srcBuffer0);
      free(srcBuffer1);
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT");
      return;
   }

   for (dstRow = 0; dstRow < dstHeight; dstRow++) {
      const GLint dstY = dstYpos + dstRow;
      const GLfloat srcRow = (dstRow * srcHeight) / dstHeightF;
      GLint srcRow0 = IFLOOR(srcRow);
      GLint srcRow1 = srcRow0 + 1;
      GLfloat rowWeight = srcRow - srcRow0; /* fractional part of srcRow */

      ASSERT(srcRow >= 0);
      ASSERT(srcRow < srcHeight);

      if (srcRow1 == srcHeight) {
         /* last row fudge */
         srcRow1 = srcRow0;
         rowWeight = 0.0;
      }

      if (invertY) {
         srcRow0 = srcHeight - 1 - srcRow0;
         srcRow1 = srcHeight - 1 - srcRow1;
      }

      srcY0 = srcYpos + srcRow0;
      srcY1 = srcYpos + srcRow1;

      /* get the two source rows */
      if (srcY0 == srcBufferY0 && srcY1 == srcBufferY1) {
         /* use same source row buffers again */
      }
      else if (srcY0 == srcBufferY1) {
         /* move buffer1 into buffer0 by swapping pointers */
         GLvoid *tmp = srcBuffer0;
         srcBuffer0 = srcBuffer1;
         srcBuffer1 = tmp;
         /* get y1 row */
         readRb->GetRow(ctx, readRb, srcWidth, srcXpos, srcY1, srcBuffer1);
         srcBufferY0 = srcY0;
         srcBufferY1 = srcY1;
      }
      else {
         /* get both new rows */
         readRb->GetRow(ctx, readRb, srcWidth, srcXpos, srcY0, srcBuffer0);
         readRb->GetRow(ctx, readRb, srcWidth, srcXpos, srcY1, srcBuffer1);
         srcBufferY0 = srcY0;
         srcBufferY1 = srcY1;
      }

      if (readRb->DataType == GL_UNSIGNED_BYTE) {
         resample_linear_row_ub(srcWidth, dstWidth, srcBuffer0, srcBuffer1,
                                dstBuffer, invertX, rowWeight);
      }
      else {
         _mesa_problem(ctx, "Unsupported color channel type in sw blit");
         break;
      }

      /* store pixel row in destination */
      drawRb->PutRow(ctx, drawRb, dstWidth, dstXpos, dstY, dstBuffer, NULL);
   }

   free(srcBuffer0);
   free(srcBuffer1);
   free(dstBuffer);
}
Exemple #6
0
static void GLAPIENTRY
_mesa_Bitmap( GLsizei width, GLsizei height,
              GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove,
              const GLubyte *bitmap )
{
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);

   if (width < 0 || height < 0) {
      _mesa_error( ctx, GL_INVALID_VALUE, "glBitmap(width or height < 0)" );
      return;
   }

   if (!ctx->Current.RasterPosValid) {
      return;    /* do nothing */
   }

   /* Note: this call does state validation */
   if (!_mesa_valid_to_render(ctx, "glBitmap")) {
      /* the error code was recorded */
      return;
   }

   if (ctx->RasterDiscard)
      return;

   if (ctx->RenderMode == GL_RENDER) {
      /* Truncate, to satisfy conformance tests (matches SGI's OpenGL). */
      if (width > 0 && height > 0) {
         const GLfloat epsilon = 0.0001F;
         GLint x = IFLOOR(ctx->Current.RasterPos[0] + epsilon - xorig);
         GLint y = IFLOOR(ctx->Current.RasterPos[1] + epsilon - yorig);

         if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
            /* unpack from PBO */
            if (!_mesa_validate_pbo_access(2, &ctx->Unpack, width, height,
                                           1, GL_COLOR_INDEX, GL_BITMAP,
                                           INT_MAX, (const GLvoid *) bitmap)) {
               _mesa_error(ctx, GL_INVALID_OPERATION,
                           "glBitmap(invalid PBO access)");
               return;
            }
            if (_mesa_bufferobj_mapped(ctx->Unpack.BufferObj)) {
               /* buffer is mapped - that's an error */
               _mesa_error(ctx, GL_INVALID_OPERATION,
                           "glBitmap(PBO is mapped)");
               return;
            }
         }

         ctx->Driver.Bitmap( ctx, x, y, width, height, &ctx->Unpack, bitmap );
      }
   }
#if _HAVE_FULL_GL
   else if (ctx->RenderMode == GL_FEEDBACK) {
      FLUSH_CURRENT(ctx, 0);
      _mesa_feedback_token( ctx, (GLfloat) (GLint) GL_BITMAP_TOKEN );
      _mesa_feedback_vertex( ctx,
                             ctx->Current.RasterPos,
                             ctx->Current.RasterColor,
                             ctx->Current.RasterTexCoords[0] );
   }
   else {
      ASSERT(ctx->RenderMode == GL_SELECT);
      /* Do nothing.  See OpenGL Spec, Appendix B, Corollary 6. */
   }
#endif

   /* update raster position */
   ctx->Current.RasterPos[0] += xmove;
   ctx->Current.RasterPos[1] += ymove;

   if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
      _mesa_flush(ctx);
   }
}
Exemple #7
0
/**
 * Called via ctx->Driver.DrawAtlasBitmap()
 */
static void
st_DrawAtlasBitmaps(struct gl_context *ctx,
                    const struct gl_bitmap_atlas *atlas,
                    GLuint count, const GLubyte *ids)
{
    struct st_context *st = st_context(ctx);
    struct pipe_context *pipe = st->pipe;
    struct st_texture_object *stObj = st_texture_object(atlas->texObj);
    struct pipe_sampler_view *sv;
    /* convert Z from [0,1] to [-1,-1] to match viewport Z scale/bias */
    const float z = ctx->Current.RasterPos[2] * 2.0f - 1.0f;
    const float *color = ctx->Current.RasterColor;
    const float clip_x_scale = 2.0f / st->state.framebuffer.width;
    const float clip_y_scale = 2.0f / st->state.framebuffer.height;
    const unsigned num_verts = count * 4;
    const unsigned num_vert_bytes = num_verts * sizeof(struct st_util_vertex);
    struct st_util_vertex *verts;
    struct pipe_vertex_buffer vb = {0};
    unsigned i;

    if (!st->bitmap.cache) {
        init_bitmap_state(st);
    }

    st_flush_bitmap_cache(st);

    st_validate_state(st, ST_PIPELINE_RENDER);
    st_invalidate_readpix_cache(st);

    sv = st_create_texture_sampler_view(pipe, stObj->pt);
    if (!sv) {
        _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCallLists(bitmap text)");
        return;
    }

    setup_render_state(ctx, sv, color, true);

    vb.stride = sizeof(struct st_util_vertex);

    u_upload_alloc(st->uploader, 0, num_vert_bytes, 4,
                   &vb.buffer_offset, &vb.buffer, (void **) &verts);

    /* build quads vertex data */
    for (i = 0; i < count; i++) {
        const GLfloat epsilon = 0.0001F;
        const struct gl_bitmap_glyph *g = &atlas->glyphs[ids[i]];
        const float xmove = g->xmove, ymove = g->ymove;
        const float xorig = g->xorig, yorig = g->yorig;
        const float s0 = g->x, t0 = g->y;
        const float s1 = s0 + g->w, t1 = t0 + g->h;
        const float x0 = IFLOOR(ctx->Current.RasterPos[0] - xorig + epsilon);
        const float y0 = IFLOOR(ctx->Current.RasterPos[1] - yorig + epsilon);
        const float x1 = x0 + g->w, y1 = y0 + g->h;
        const float clip_x0 = x0 * clip_x_scale - 1.0f;
        const float clip_y0 = y0 * clip_y_scale - 1.0f;
        const float clip_x1 = x1 * clip_x_scale - 1.0f;
        const float clip_y1 = y1 * clip_y_scale - 1.0f;

        /* lower-left corner */
        verts->x = clip_x0;
        verts->y = clip_y0;
        verts->z = z;
        verts->r = color[0];
        verts->g = color[1];
        verts->b = color[2];
        verts->a = color[3];
        verts->s = s0;
        verts->t = t0;
        verts++;

        /* lower-right corner */
        verts->x = clip_x1;
        verts->y = clip_y0;
        verts->z = z;
        verts->r = color[0];
        verts->g = color[1];
        verts->b = color[2];
        verts->a = color[3];
        verts->s = s1;
        verts->t = t0;
        verts++;

        /* upper-right corner */
        verts->x = clip_x1;
        verts->y = clip_y1;
        verts->z = z;
        verts->r = color[0];
        verts->g = color[1];
        verts->b = color[2];
        verts->a = color[3];
        verts->s = s1;
        verts->t = t1;
        verts++;

        /* upper-left corner */
        verts->x = clip_x0;
        verts->y = clip_y1;
        verts->z = z;
        verts->r = color[0];
        verts->g = color[1];
        verts->b = color[2];
        verts->a = color[3];
        verts->s = s0;
        verts->t = t1;
        verts++;

        /* Update the raster position */
        ctx->Current.RasterPos[0] += xmove;
        ctx->Current.RasterPos[1] += ymove;
    }

    u_upload_unmap(st->uploader);

    cso_set_vertex_buffers(st->cso_context,
                           cso_get_aux_vertex_buffer_slot(st->cso_context),
                           1, &vb);

    cso_draw_arrays(st->cso_context, PIPE_PRIM_QUADS, 0, num_verts);

    restore_render_state(ctx);

    pipe_resource_reference(&vb.buffer, NULL);

    pipe_sampler_view_reference(&sv, NULL);

    /* We uploaded modified constants, need to invalidate them. */
    st->dirty |= ST_NEW_FS_CONSTANTS;
}
Exemple #8
0
static void GLAPIENTRY
_mesa_Bitmap( GLsizei width, GLsizei height,
              GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove,
              const GLubyte *bitmap )
{
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);

   if (width < 0 || height < 0) {
      _mesa_error( ctx, GL_INVALID_VALUE, "glBitmap(width or height < 0)" );
      return;
   }

   if (!ctx->Current.RasterPosValid) {
      return;    /* do nothing */
   }

   if (ctx->NewState) {
      _mesa_update_state(ctx);
   }

   if (!valid_fragment_program(ctx)) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "glBitmap (invalid fragment program)");
      return;
   }

   if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
      _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
                  "glBitmap(incomplete framebuffer)");
      return;
   }

   if (ctx->RenderMode == GL_RENDER) {
      /* Truncate, to satisfy conformance tests (matches SGI's OpenGL). */
      if (width > 0 && height > 0) {
         const GLfloat epsilon = 0.0001F;
         GLint x = IFLOOR(ctx->Current.RasterPos[0] + epsilon - xorig);
         GLint y = IFLOOR(ctx->Current.RasterPos[1] + epsilon - yorig);

         if (ctx->Unpack.BufferObj->Name) {
            /* unpack from PBO */
            if (!_mesa_validate_pbo_access(2, &ctx->Unpack, width, height, 1,
                                           GL_COLOR_INDEX, GL_BITMAP,
                                           (GLvoid *) bitmap)) {
               _mesa_error(ctx, GL_INVALID_OPERATION,
                           "glBitmap(invalid PBO access)");
               return;
            }
            if (_mesa_bufferobj_mapped(ctx->Unpack.BufferObj)) {
               /* buffer is mapped - that's an error */
               _mesa_error(ctx, GL_INVALID_OPERATION,
                           "glBitmap(PBO is mapped)");
               return;
            }
         }

         ctx->Driver.Bitmap( ctx, x, y, width, height, &ctx->Unpack, bitmap );
      }
   }
#if _HAVE_FULL_GL
   else if (ctx->RenderMode == GL_FEEDBACK) {
      FLUSH_CURRENT(ctx, 0);
      _mesa_feedback_token( ctx, (GLfloat) (GLint) GL_BITMAP_TOKEN );
      _mesa_feedback_vertex( ctx,
                             ctx->Current.RasterPos,
                             ctx->Current.RasterColor,
                             ctx->Current.RasterIndex, 
                             ctx->Current.RasterTexCoords[0] );
   }
   else {
      ASSERT(ctx->RenderMode == GL_SELECT);
      /* Do nothing.  See OpenGL Spec, Appendix B, Corollary 6. */
   }
#endif

   /* update raster position */
   ctx->Current.RasterPos[0] += xmove;
   ctx->Current.RasterPos[1] += ymove;
}
Exemple #9
0
void GLAPIENTRY
_mesa_Bitmap( GLsizei width, GLsizei height,
              GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove,
              const GLubyte *bitmap )
{
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);

   if (width < 0 || height < 0) {
      _mesa_error( ctx, GL_INVALID_VALUE, "glBitmap(width or height < 0)" );
      return;
   }

   if (!ctx->Current.RasterPosValid) {
      return;    /* do nothing */
   }

   if (ctx->NewState) {
      _mesa_update_state(ctx);
   }

   if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "glBitmap (invalid fragment program)");
      return;
   }

   if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
      _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
                  "glBitmap(incomplete framebuffer)");
      return;
   }

   if (ctx->RenderMode == GL_RENDER) {
      if (bitmap) {
         /* Truncate, to satisfy conformance tests (matches SGI's OpenGL). */
         GLint x = IFLOOR(ctx->Current.RasterPos[0] - xorig);
         GLint y = IFLOOR(ctx->Current.RasterPos[1] - yorig);
         ctx->Driver.Bitmap( ctx, x, y, width, height, &ctx->Unpack, bitmap );
      }
   }
#if _HAVE_FULL_GL
   else if (ctx->RenderMode == GL_FEEDBACK) {
      FLUSH_CURRENT(ctx, 0);
      FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_BITMAP_TOKEN );
      _mesa_feedback_vertex( ctx,
                             ctx->Current.RasterPos,
                             ctx->Current.RasterColor,
                             ctx->Current.RasterIndex, 
                             ctx->Current.RasterTexCoords[0] );
   }
   else {
      ASSERT(ctx->RenderMode == GL_SELECT);
      /* Do nothing.  See OpenGL Spec, Appendix B, Corollary 6. */
   }
#endif

   /* update raster position */
   ctx->Current.RasterPos[0] += xmove;
   ctx->Current.RasterPos[1] += ymove;
}
Exemple #10
0
/**
 * Bilinear filtered blit (color only, non-integer values).
 */
static void
blit_linear(struct gl_context *ctx,
            GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
            GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1)
{
   struct gl_renderbuffer *readRb = ctx->ReadBuffer->_ColorReadBuffer;
   struct gl_renderbuffer *drawRb = ctx->DrawBuffer->_ColorDrawBuffers[0];

   const GLint srcWidth = ABS(srcX1 - srcX0);
   const GLint dstWidth = ABS(dstX1 - dstX0);
   const GLint srcHeight = ABS(srcY1 - srcY0);
   const GLint dstHeight = ABS(dstY1 - dstY0);
   const GLfloat dstHeightF = (GLfloat) dstHeight;

   const GLint srcXpos = MIN2(srcX0, srcX1);
   const GLint srcYpos = MIN2(srcY0, srcY1);
   const GLint dstXpos = MIN2(dstX0, dstX1);
   const GLint dstYpos = MIN2(dstY0, dstY1);

   const GLboolean invertX = (srcX1 < srcX0) ^ (dstX1 < dstX0);
   const GLboolean invertY = (srcY1 < srcY0) ^ (dstY1 < dstY0);

   GLint dstRow;

   GLint pixelSize;
   GLvoid *srcBuffer0, *srcBuffer1;
   GLint srcBufferY0 = -1, srcBufferY1 = -1;
   GLvoid *dstBuffer;

   gl_format readFormat = _mesa_get_srgb_format_linear(readRb->Format);
   gl_format drawFormat = _mesa_get_srgb_format_linear(drawRb->Format);
   GLuint bpp = _mesa_get_format_bytes(readFormat);

   GLenum pixelType;

   GLubyte *srcMap, *dstMap;
   GLint srcRowStride, dstRowStride;


   /* Determine datatype for resampling */
   if (_mesa_get_format_max_bits(readFormat) == 8 &&
       _mesa_get_format_datatype(readFormat) == GL_UNSIGNED_NORMALIZED) {
      pixelType = GL_UNSIGNED_BYTE;
      pixelSize = 4 * sizeof(GLubyte);
   }
   else {
      pixelType = GL_FLOAT;
      pixelSize = 4 * sizeof(GLfloat);
   }

   /* Allocate the src/dst row buffers.
    * Keep two adjacent src rows around for bilinear sampling.
    */
   srcBuffer0 = malloc(pixelSize * srcWidth);
   if (!srcBuffer0) {
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT");
      return;
   }
   srcBuffer1 = malloc(pixelSize * srcWidth);
   if (!srcBuffer1) {
      free(srcBuffer0);
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT");
      return;
   }
   dstBuffer = malloc(pixelSize * dstWidth);
   if (!dstBuffer) {
      free(srcBuffer0);
      free(srcBuffer1);
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT");
      return;
   }

   /*
    * Map src / dst renderbuffers
    */
   if (readRb == drawRb) {
      /* map whole buffer for read/write */
      ctx->Driver.MapRenderbuffer(ctx, readRb,
                                  0, 0, readRb->Width, readRb->Height,
                                  GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
                                  &srcMap, &srcRowStride);
      if (!srcMap) {
         free(srcBuffer0);
         free(srcBuffer1);
         free(dstBuffer);
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer");
         return;
      }

      dstMap = srcMap;
      dstRowStride = srcRowStride;
   }
   else {
      /* different src/dst buffers */
      /* XXX with a bit of work we could just map the regions to be
       * read/written instead of the whole buffers.
       */
      ctx->Driver.MapRenderbuffer(ctx, readRb,
				  0, 0, readRb->Width, readRb->Height,
                                  GL_MAP_READ_BIT, &srcMap, &srcRowStride);
      if (!srcMap) {
         free(srcBuffer0);
         free(srcBuffer1);
         free(dstBuffer);
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer");
         return;
      }
      ctx->Driver.MapRenderbuffer(ctx, drawRb,
                                  0, 0, drawRb->Width, drawRb->Height,
                                  GL_MAP_WRITE_BIT, &dstMap, &dstRowStride);
      if (!dstMap) {
         ctx->Driver.UnmapRenderbuffer(ctx, readRb);
         free(srcBuffer0);
         free(srcBuffer1);
         free(dstBuffer);
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer");
         return;
      }
   }

   for (dstRow = 0; dstRow < dstHeight; dstRow++) {
      const GLint dstY = dstYpos + dstRow;
      const GLfloat srcRow = (dstRow * srcHeight) / dstHeightF;
      GLint srcRow0 = IFLOOR(srcRow);
      GLint srcRow1 = srcRow0 + 1;
      GLfloat rowWeight = srcRow - srcRow0; /* fractional part of srcRow */

      ASSERT(srcRow >= 0);
      ASSERT(srcRow < srcHeight);

      if (srcRow1 == srcHeight) {
         /* last row fudge */
         srcRow1 = srcRow0;
         rowWeight = 0.0;
      }

      if (invertY) {
         srcRow0 = srcHeight - 1 - srcRow0;
         srcRow1 = srcHeight - 1 - srcRow1;
      }

      srcY0 = srcYpos + srcRow0;
      srcY1 = srcYpos + srcRow1;

      /* get the two source rows */
      if (srcY0 == srcBufferY0 && srcY1 == srcBufferY1) {
         /* use same source row buffers again */
      }
      else if (srcY0 == srcBufferY1) {
         /* move buffer1 into buffer0 by swapping pointers */
         GLvoid *tmp = srcBuffer0;
         srcBuffer0 = srcBuffer1;
         srcBuffer1 = tmp;
         /* get y1 row */
         {
            GLubyte *src = srcMap + srcY1 * srcRowStride + srcXpos * bpp;
            if (pixelType == GL_UNSIGNED_BYTE) {
               _mesa_unpack_ubyte_rgba_row(readFormat, srcWidth,
                                           src, srcBuffer1);
            }
            else {
               _mesa_unpack_rgba_row(readFormat, srcWidth,
                                     src, srcBuffer1);
            }
         }            
         srcBufferY0 = srcY0;
         srcBufferY1 = srcY1;
      }
      else {
         /* get both new rows */
         {
            GLubyte *src0 = srcMap + srcY0 * srcRowStride + srcXpos * bpp;
            GLubyte *src1 = srcMap + srcY1 * srcRowStride + srcXpos * bpp;
            if (pixelType == GL_UNSIGNED_BYTE) {
               _mesa_unpack_ubyte_rgba_row(readFormat, srcWidth,
                                           src0, srcBuffer0);
               _mesa_unpack_ubyte_rgba_row(readFormat, srcWidth,
                                           src1, srcBuffer1);
            }
            else {
               _mesa_unpack_rgba_row(readFormat, srcWidth, src0, srcBuffer0);
               _mesa_unpack_rgba_row(readFormat, srcWidth, src1, srcBuffer1);
            }
         }
         srcBufferY0 = srcY0;
         srcBufferY1 = srcY1;
      }

      if (pixelType == GL_UNSIGNED_BYTE) {
         resample_linear_row_ub(srcWidth, dstWidth, srcBuffer0, srcBuffer1,
                                dstBuffer, invertX, rowWeight);
      }
      else {
         resample_linear_row_float(srcWidth, dstWidth, srcBuffer0, srcBuffer1,
                                   dstBuffer, invertX, rowWeight);
      }

      /* store pixel row in destination */
      {
         GLubyte *dst = dstMap + dstY * dstRowStride + dstXpos * bpp;
         if (pixelType == GL_UNSIGNED_BYTE) {
            _mesa_pack_ubyte_rgba_row(drawFormat, dstWidth, dstBuffer, dst);
         }
         else {
            _mesa_pack_float_rgba_row(drawFormat, dstWidth, dstBuffer, dst);
         }
      }
   }

   free(srcBuffer0);
   free(srcBuffer1);
   free(dstBuffer);

   ctx->Driver.UnmapRenderbuffer(ctx, readRb);
   if (drawRb != readRb) {
      ctx->Driver.UnmapRenderbuffer(ctx, drawRb);
   }
}
Exemple #11
0
void
fxyQuadFwdSpatBil ( ppf dst, ppf wts, ppf qxyB, ppf qxyC
                  , ppf pre0, ppf pre1, ppf pre2, unt dW, unt dH, dbl trans)
{
  unt   j, k;
  int   kT, jT, wM = dW-1, hM = dH-1;
  pfl   pB, pC, p0, p1, p2;
  flt	xT, yT, xM, yM, dV;
  flt	trs = (flt) trans;
  flt	tr2 = (flt)(trans*trans);
  flt	w0  = (flt)(1.0 - trs*2.0 + tr2);
  flt	w1  = (flt)((trs - tr2)*2.0);
  flt	w2  = tr2;
  flt	wT  = w0 + w1 + w2;
  w0 /= wT; w1 /= wT; w2 /= wT;
  dV  = w0 + w1 + w2;
#if 1	/**************************************/
  dV -= 1.0;
  if (dV < 0.0)  dV = -dV;
  assert(dV < 0.001);
#else	/**************************************/
  if (trans < 0.5)  w1 = 2.0*trans,     w0 = 1.0 - w1, w2 = 0.0;
  else              w2 = 2.0*trans-1.0, w1 = 1.0 - w2, w0 = 0.0;
#endif	/**************************************/
  rowZeroF(dst,0,0,dW,dH);
  rowZeroF(wts,0,0,dW,dH);
  for (j = 0; j < dH; j++) {
    pB  = *qxyB++ ; pC = *qxyC++ ;
    p0  = *pre0++ ; p1 = *pre1++ ; p2 = *pre2++;
    for (k = 0; k < dW; k++) {
      xT = k + trs * *pB++ + tr2 * *pC++;
      kT = IFLOOR(xT);
      if (0 <= kT && kT < wM) {
        yT = j + trs * *pB++ + tr2 * *pC++;
        jT = IFLOOR(yT);
        if (0 <= jT && jT < hM) {
          xT -= kT;
          xM  = 1.0F - xT;
          yT -= jT;
          yM  = 1.0F - yT;
          dV = w0**p0++ + w1**p1++ + w2**p2++;

          wT           = xM*yM;
          wts[jT][kT] += wT;
          dst[jT][kT] += wT*dV;

          kT++;
          wT           = xT*yM;
          wts[jT][kT] += wT;
          dst[jT][kT] += wT*dV;

          jT++;
          wT           = xT*yT;
          wts[jT][kT] += wT;
          dst[jT][kT] += wT*dV;

          kT--;
          wT           = xM*yT;
          wts[jT][kT] += wT;
          dst[jT][kT] += wT*dV;
        }
        else { p0++; p1++; p2++; }
      }
      else { p0++; p1++; p2++; pB++; pC++; }
    }
  }
}