Exemple #1
0
/**
 * Enable or disable writing of frame buffer color components.
 *
 * \param red whether to mask writing of the red color component.
 * \param green whether to mask writing of the green color component.
 * \param blue whether to mask writing of the blue color component.
 * \param alpha whether to mask writing of the alpha color component.
 *
 * \sa glColorMask().
 *
 * Sets the appropriate value of gl_colorbuffer_attrib::ColorMask.  On a
 * change, flushes the vertices and notifies the driver via the
 * dd_function_table::ColorMask callback.
 */
void GLAPIENTRY
_mesa_ColorMask( GLboolean red, GLboolean green,
                 GLboolean blue, GLboolean alpha )
{
   GET_CURRENT_CONTEXT(ctx);
   GLubyte tmp[4];
   GLuint i;
   GLboolean flushed;

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glColorMask(%d, %d, %d, %d)\n",
                  red, green, blue, alpha);

   /* Shouldn't have any information about channel depth in core mesa
    * -- should probably store these as the native booleans:
    */
   tmp[RCOMP] = red    ? 0xff : 0x0;
   tmp[GCOMP] = green  ? 0xff : 0x0;
   tmp[BCOMP] = blue   ? 0xff : 0x0;
   tmp[ACOMP] = alpha  ? 0xff : 0x0;

   flushed = GL_FALSE;
   for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
      if (!TEST_EQ_4V(tmp, ctx->Color.ColorMask[i])) {
         if (!flushed) {
            FLUSH_VERTICES(ctx, _NEW_COLOR);
         }
         flushed = GL_TRUE;
         COPY_4UBV(ctx->Color.ColorMask[i], tmp);
      }
   }

   if (ctx->Driver.ColorMask)
      ctx->Driver.ColorMask( ctx, red, green, blue, alpha );
}
Exemple #2
0
/**
 * For GL_EXT_draw_buffers2 and GL3
 */
void GLAPIENTRY
_mesa_ColorMaski( GLuint buf, GLboolean red, GLboolean green,
                        GLboolean blue, GLboolean alpha )
{
   GLubyte tmp[4];
   GET_CURRENT_CONTEXT(ctx);

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glColorMaskIndexed %u %d %d %d %d\n",
                  buf, red, green, blue, alpha);

   if (buf >= ctx->Const.MaxDrawBuffers) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glColorMaskIndexed(buf=%u)", buf);
      return;
   }

   /* Shouldn't have any information about channel depth in core mesa
    * -- should probably store these as the native booleans:
    */
   tmp[RCOMP] = red    ? 0xff : 0x0;
   tmp[GCOMP] = green  ? 0xff : 0x0;
   tmp[BCOMP] = blue   ? 0xff : 0x0;
   tmp[ACOMP] = alpha  ? 0xff : 0x0;

   if (TEST_EQ_4V(tmp, ctx->Color.ColorMask[buf]))
      return;

   FLUSH_VERTICES(ctx, _NEW_COLOR);
   COPY_4UBV(ctx->Color.ColorMask[buf], tmp);
}
Exemple #3
0
/**
 * Enable or disable writing of frame buffer color components.
 *
 * \param red whether to mask writing of the red color component.
 * \param green whether to mask writing of the green color component.
 * \param blue whether to mask writing of the blue color component.
 * \param alpha whether to mask writing of the alpha color component.
 *
 * \sa glColorMask().
 *
 * Sets the appropriate value of gl_colorbuffer_attrib::ColorMask.  On a
 * change, flushes the vertices and notifies the driver via the
 * dd_function_table::ColorMask callback.
 */
void GLAPIENTRY
_mesa_ColorMask( GLboolean red, GLboolean green,
                 GLboolean blue, GLboolean alpha )
{
   GET_CURRENT_CONTEXT(ctx);
   GLubyte tmp[4];
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glColorMask %d %d %d %d\n", red, green, blue, alpha);

   /* Shouldn't have any information about channel depth in core mesa
    * -- should probably store these as the native booleans:
    */
   tmp[RCOMP] = red    ? 0xff : 0x0;
   tmp[GCOMP] = green  ? 0xff : 0x0;
   tmp[BCOMP] = blue   ? 0xff : 0x0;
   tmp[ACOMP] = alpha  ? 0xff : 0x0;

   if (TEST_EQ_4UBV(tmp, ctx->Color.ColorMask))
      return;

   FLUSH_VERTICES(ctx, _NEW_COLOR);
   COPY_4UBV(ctx->Color.ColorMask, tmp);

   if (ctx->Driver.ColorMask)
      ctx->Driver.ColorMask( ctx, red, green, blue, alpha );
}
Exemple #4
0
/**
 * Clear the color buffer when glColorMask is in effect.
 */
static void
clear_rgba_buffer_with_masking(GLcontext *ctx, struct gl_renderbuffer *rb)
{
   const GLint x = ctx->DrawBuffer->_Xmin;
   const GLint y = ctx->DrawBuffer->_Ymin;
   const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
   const GLint width  = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
   SWspan span;
   GLint i;

   ASSERT(ctx->Visual.rgbMode);
   ASSERT(rb->PutRow);

   /* Initialize color span with clear color */
   /* XXX optimize for clearcolor == black/zero (bzero) */
   INIT_SPAN(span, GL_BITMAP, width, 0, SPAN_RGBA);
   span.array->ChanType = rb->DataType;
   if (span.array->ChanType == GL_UNSIGNED_BYTE) {
      GLubyte clearColor[4];
      UNCLAMPED_FLOAT_TO_UBYTE(clearColor[RCOMP], ctx->Color.ClearColor[0]);
      UNCLAMPED_FLOAT_TO_UBYTE(clearColor[GCOMP], ctx->Color.ClearColor[1]);
      UNCLAMPED_FLOAT_TO_UBYTE(clearColor[BCOMP], ctx->Color.ClearColor[2]);
      UNCLAMPED_FLOAT_TO_UBYTE(clearColor[ACOMP], ctx->Color.ClearColor[3]);
      for (i = 0; i < width; i++) {
         COPY_4UBV(span.array->rgba[i], clearColor);
      }
   }
   else if (span.array->ChanType == GL_UNSIGNED_SHORT) {
      GLushort clearColor[4];
      UNCLAMPED_FLOAT_TO_USHORT(clearColor[RCOMP], ctx->Color.ClearColor[0]);
      UNCLAMPED_FLOAT_TO_USHORT(clearColor[GCOMP], ctx->Color.ClearColor[1]);
      UNCLAMPED_FLOAT_TO_USHORT(clearColor[BCOMP], ctx->Color.ClearColor[2]);
      UNCLAMPED_FLOAT_TO_USHORT(clearColor[ACOMP], ctx->Color.ClearColor[3]);
      for (i = 0; i < width; i++) {
         COPY_4V(span.array->rgba[i], clearColor);
      }
   }
   else {
      ASSERT(span.array->ChanType == GL_FLOAT);
      for (i = 0; i < width; i++) {
         CLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][0], ctx->Color.ClearColor[0]);
         CLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][1], ctx->Color.ClearColor[1]);
         CLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][2], ctx->Color.ClearColor[2]);
         CLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][3], ctx->Color.ClearColor[3]);
      }
   }

   /* Note that masking will change the color values, but only the
    * channels for which the write mask is GL_FALSE.  The channels
    * which which are write-enabled won't get modified.
    */
   for (i = 0; i < height; i++) {
      span.x = x;
      span.y = y + i;
      _swrast_mask_rgba_span(ctx, rb, &span);
      /* write masked row */
      rb->PutRow(ctx, rb, width, x, y + i, span.array->rgba, NULL);
   }
}
Exemple #5
0
static void trans_4_GLubyte_4ub(GLubyte (*t)[4],
				const struct gl_client_array *from,
				ARGS )
{
   GLuint stride = from->StrideB;
   const GLubyte *f = (GLubyte *) from->Ptr + SRC_START * stride;
   const GLubyte *first = f;
   GLuint i;
   (void) start;
   if (((((long) f | (long) stride)) & 3L) == 0L) { 
      /* Aligned.
       */
      for (i = DST_START ; i < n ; i++, NEXT_F) {
	 CHECK {
	    NEXT_F2;
	    COPY_4UBV( t[i], f );
	 }
      }
   } else {
      for (i = DST_START ; i < n ; i++, NEXT_F) {
Exemple #6
0
static void trans_4_GLubyte_4ub_raw(GLubyte (*t)[4],
				    const void *Ptr,
				    GLuint stride,
				    ARGS )
{
   const GLubyte *f = (GLubyte *) Ptr + SRC_START * stride;
   GLuint i;

   if (((((uintptr_t) f | (uintptr_t) stride)) & 3L) == 0L) {
      /* Aligned.
       */
      for (i = DST_START ; i < n ; i++, f += stride) {
	 COPY_4UBV( t[i], f );
      }
   } else {
      for (i = DST_START ; i < n ; i++, f += stride) {
	 t[i][0] = f[0];
	 t[i][1] = f[1];
	 t[i][2] = f[2];
	 t[i][3] = f[3];
      }
   }
}
Exemple #7
0
static void trans_4_GLubyte_4ub_raw (GLubyte (*t)[4],
				     const struct gl_client_array *from,
				     ARGS )
{
   GLuint stride = from->StrideB;
   const GLubyte *f = (GLubyte *) from->Ptr + SRC_START * stride;
   GLuint i;

   if (((((long) f | (long) stride)) & 3L) == 0L) { 
      /* Aligned.
       */
      for (i = DST_START ; i < n ; i++, f += stride) {
	 COPY_4UBV( t[i], f );
      }
   } else {
      for (i = DST_START ; i < n ; i++, f += stride) {
	 t[i][0] = f[0];
	 t[i][1] = f[1];
	 t[i][2] = f[2];
	 t[i][3] = f[3];
      }
   }
}
Exemple #8
0
/**
 * Helper function called from _swrast_write_zoomed_rgba/rgb/
 * index/depth_span().
 */
static void
zoom_span( struct gl_context *ctx, GLint imgX, GLint imgY, const SWspan *span,
           const GLvoid *src, GLenum format )
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
   SWspan zoomed;
   GLint x0, x1, y0, y1;
   GLint zoomedWidth;

   if (!compute_zoomed_bounds(ctx, imgX, imgY, span->x, span->y, span->end,
                              &x0, &x1, &y0, &y1)) {
      return;  /* totally clipped */
   }

   if (!swrast->ZoomedArrays) {
      /* allocate on demand */
      swrast->ZoomedArrays = (SWspanarrays *) CALLOC(sizeof(SWspanarrays));
      if (!swrast->ZoomedArrays)
         return;
   }

   zoomedWidth = x1 - x0;
   ASSERT(zoomedWidth > 0);
   ASSERT(zoomedWidth <= MAX_WIDTH);

   /* no pixel arrays! must be horizontal spans. */
   ASSERT((span->arrayMask & SPAN_XY) == 0);
   ASSERT(span->primitive == GL_BITMAP);

   INIT_SPAN(zoomed, GL_BITMAP);
   zoomed.x = x0;
   zoomed.end = zoomedWidth;
   zoomed.array = swrast->ZoomedArrays;
   zoomed.array->ChanType = span->array->ChanType;
   if (zoomed.array->ChanType == GL_UNSIGNED_BYTE)
      zoomed.array->rgba = (GLchan (*)[4]) zoomed.array->rgba8;
   else if (zoomed.array->ChanType == GL_UNSIGNED_SHORT)
      zoomed.array->rgba = (GLchan (*)[4]) zoomed.array->rgba16;
   else
      zoomed.array->rgba = (GLchan (*)[4]) zoomed.array->attribs[FRAG_ATTRIB_COL];

   COPY_4V(zoomed.attrStart[FRAG_ATTRIB_WPOS], span->attrStart[FRAG_ATTRIB_WPOS]);
   COPY_4V(zoomed.attrStepX[FRAG_ATTRIB_WPOS], span->attrStepX[FRAG_ATTRIB_WPOS]);
   COPY_4V(zoomed.attrStepY[FRAG_ATTRIB_WPOS], span->attrStepY[FRAG_ATTRIB_WPOS]);

   zoomed.attrStart[FRAG_ATTRIB_FOGC][0] = span->attrStart[FRAG_ATTRIB_FOGC][0];
   zoomed.attrStepX[FRAG_ATTRIB_FOGC][0] = span->attrStepX[FRAG_ATTRIB_FOGC][0];
   zoomed.attrStepY[FRAG_ATTRIB_FOGC][0] = span->attrStepY[FRAG_ATTRIB_FOGC][0];

   if (format == GL_RGBA || format == GL_RGB) {
      /* copy Z info */
      zoomed.z = span->z;
      zoomed.zStep = span->zStep;
      /* we'll generate an array of colorss */
      zoomed.interpMask = span->interpMask & ~SPAN_RGBA;
      zoomed.arrayMask |= SPAN_RGBA;
      zoomed.arrayAttribs |= FRAG_BIT_COL;  /* we'll produce these values */
      ASSERT(span->arrayMask & SPAN_RGBA);
   }
   else if (format == GL_DEPTH_COMPONENT) {
      /* Copy color info */
      zoomed.red = span->red;
      zoomed.green = span->green;
      zoomed.blue = span->blue;
      zoomed.alpha = span->alpha;
      zoomed.redStep = span->redStep;
      zoomed.greenStep = span->greenStep;
      zoomed.blueStep = span->blueStep;
      zoomed.alphaStep = span->alphaStep;
      /* we'll generate an array of depth values */
      zoomed.interpMask = span->interpMask & ~SPAN_Z;
      zoomed.arrayMask |= SPAN_Z;
      ASSERT(span->arrayMask & SPAN_Z);
   }
   else {
      _mesa_problem(ctx, "Bad format in zoom_span");
      return;
   }

   /* zoom the span horizontally */
   if (format == GL_RGBA) {
      if (zoomed.array->ChanType == GL_UNSIGNED_BYTE) {
         const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) src;
         GLint i;
         for (i = 0; i < zoomedWidth; i++) {
            GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
            ASSERT(j >= 0);
            ASSERT(j < (GLint) span->end);
            COPY_4UBV(zoomed.array->rgba8[i], rgba[j]);
         }
      }
      else if (zoomed.array->ChanType == GL_UNSIGNED_SHORT) {
         const GLushort (*rgba)[4] = (const GLushort (*)[4]) src;
         GLint i;
         for (i = 0; i < zoomedWidth; i++) {
            GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
            ASSERT(j >= 0);
            ASSERT(j < (GLint) span->end);
            COPY_4V(zoomed.array->rgba16[i], rgba[j]);
         }
      }
      else {
         const GLfloat (*rgba)[4] = (const GLfloat (*)[4]) src;
         GLint i;
         for (i = 0; i < zoomedWidth; i++) {
            GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
            ASSERT(j >= 0);
            ASSERT(j < span->end);
            COPY_4V(zoomed.array->attribs[FRAG_ATTRIB_COL][i], rgba[j]);
         }
      }
   }
   else if (format == GL_RGB) {
      if (zoomed.array->ChanType == GL_UNSIGNED_BYTE) {
         const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) src;
         GLint i;
         for (i = 0; i < zoomedWidth; i++) {
            GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
            ASSERT(j >= 0);
            ASSERT(j < (GLint) span->end);
            zoomed.array->rgba8[i][0] = rgb[j][0];
            zoomed.array->rgba8[i][1] = rgb[j][1];
            zoomed.array->rgba8[i][2] = rgb[j][2];
            zoomed.array->rgba8[i][3] = 0xff;
         }
      }
      else if (zoomed.array->ChanType == GL_UNSIGNED_SHORT) {
         const GLushort (*rgb)[3] = (const GLushort (*)[3]) src;
         GLint i;
         for (i = 0; i < zoomedWidth; i++) {
            GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
            ASSERT(j >= 0);
            ASSERT(j < (GLint) span->end);
            zoomed.array->rgba16[i][0] = rgb[j][0];
            zoomed.array->rgba16[i][1] = rgb[j][1];
            zoomed.array->rgba16[i][2] = rgb[j][2];
            zoomed.array->rgba16[i][3] = 0xffff;
         }
      }
      else {
         const GLfloat (*rgb)[3] = (const GLfloat (*)[3]) src;
         GLint i;
         for (i = 0; i < zoomedWidth; i++) {
            GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
            ASSERT(j >= 0);
            ASSERT(j < span->end);
            zoomed.array->attribs[FRAG_ATTRIB_COL][i][0] = rgb[j][0];
            zoomed.array->attribs[FRAG_ATTRIB_COL][i][1] = rgb[j][1];
            zoomed.array->attribs[FRAG_ATTRIB_COL][i][2] = rgb[j][2];
            zoomed.array->attribs[FRAG_ATTRIB_COL][i][3] = 1.0F;
         }
      }
   }
   else if (format == GL_DEPTH_COMPONENT) {
      const GLuint *zValues = (const GLuint *) src;
      GLint i;
      for (i = 0; i < zoomedWidth; i++) {
         GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
         ASSERT(j >= 0);
         ASSERT(j < (GLint) span->end);
         zoomed.array->z[i] = zValues[j];
      }
      /* Now, fall into the RGB path below */
      format = GL_RGBA;
   }

   /* write the span in rows [r0, r1) */
   if (format == GL_RGBA || format == GL_RGB) {
      /* Writing the span may modify the colors, so make a backup now if we're
       * going to call _swrast_write_zoomed_span() more than once.
       * Also, clipping may change the span end value, so store it as well.
       */
      const GLint end = zoomed.end; /* save */
      void *rgbaSave;
      const GLint pixelSize =
         (zoomed.array->ChanType == GL_UNSIGNED_BYTE) ? 4 * sizeof(GLubyte) :
         ((zoomed.array->ChanType == GL_UNSIGNED_SHORT) ? 4 * sizeof(GLushort)
          : 4 * sizeof(GLfloat));

      rgbaSave = malloc(zoomed.end * pixelSize);
      if (!rgbaSave) {
         return;
      }

      if (y1 - y0 > 1) {
         memcpy(rgbaSave, zoomed.array->rgba, zoomed.end * pixelSize);
      }
      for (zoomed.y = y0; zoomed.y < y1; zoomed.y++) {
         _swrast_write_rgba_span(ctx, &zoomed);
         zoomed.end = end;  /* restore */
         if (y1 - y0 > 1) {
            /* restore the colors */
            memcpy(zoomed.array->rgba, rgbaSave, zoomed.end * pixelSize);
         }
      }

      free(rgbaSave);
   }
}
Exemple #9
0
/**
 * Interpolate primary colors to fill in the span->array->rgba8 (or rgb16)
 * color array.
 */
static inline void
interpolate_int_colors(struct gl_context *ctx, SWspan *span)
{
#if CHAN_BITS != 32
   const GLuint n = span->end;
   GLuint i;

   ASSERT(!(span->arrayMask & SPAN_RGBA));
#endif

   switch (span->array->ChanType) {
#if CHAN_BITS != 32
   case GL_UNSIGNED_BYTE:
      {
         GLubyte (*rgba)[4] = span->array->rgba8;
         if (span->interpMask & SPAN_FLAT) {
            GLubyte color[4];
            color[RCOMP] = FixedToInt(span->red);
            color[GCOMP] = FixedToInt(span->green);
            color[BCOMP] = FixedToInt(span->blue);
            color[ACOMP] = FixedToInt(span->alpha);
            for (i = 0; i < n; i++) {
               COPY_4UBV(rgba[i], color);
            }
         }
         else {
            GLfixed r = span->red;
            GLfixed g = span->green;
            GLfixed b = span->blue;
            GLfixed a = span->alpha;
            GLint dr = span->redStep;
            GLint dg = span->greenStep;
            GLint db = span->blueStep;
            GLint da = span->alphaStep;
            for (i = 0; i < n; i++) {
               rgba[i][RCOMP] = FixedToChan(r);
               rgba[i][GCOMP] = FixedToChan(g);
               rgba[i][BCOMP] = FixedToChan(b);
               rgba[i][ACOMP] = FixedToChan(a);
               r += dr;
               g += dg;
               b += db;
               a += da;
            }
         }
      }
      break;
   case GL_UNSIGNED_SHORT:
      {
         GLushort (*rgba)[4] = span->array->rgba16;
         if (span->interpMask & SPAN_FLAT) {
            GLushort color[4];
            color[RCOMP] = FixedToInt(span->red);
            color[GCOMP] = FixedToInt(span->green);
            color[BCOMP] = FixedToInt(span->blue);
            color[ACOMP] = FixedToInt(span->alpha);
            for (i = 0; i < n; i++) {
               COPY_4V(rgba[i], color);
            }
         }
         else {
            GLushort (*rgba)[4] = span->array->rgba16;
            GLfixed r, g, b, a;
            GLint dr, dg, db, da;
            r = span->red;
            g = span->green;
            b = span->blue;
            a = span->alpha;
            dr = span->redStep;
            dg = span->greenStep;
            db = span->blueStep;
            da = span->alphaStep;
            for (i = 0; i < n; i++) {
               rgba[i][RCOMP] = FixedToChan(r);
               rgba[i][GCOMP] = FixedToChan(g);
               rgba[i][BCOMP] = FixedToChan(b);
               rgba[i][ACOMP] = FixedToChan(a);
               r += dr;
               g += dg;
               b += db;
               a += da;
            }
         }
      }
      break;
#endif
   case GL_FLOAT:
      interpolate_active_attribs(ctx, span, FRAG_BIT_COL);
      break;
   default:
      _mesa_problem(ctx, "bad datatype 0x%x in interpolate_int_colors",
                    span->array->ChanType);
   }
   span->arrayMask |= SPAN_RGBA;
}