⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 s_drawpix.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 3 页
字号:
         for (row = 0; row < height; row++, spanY++) {
            GLfloat floatSpan[MAX_WIDTH];
            const GLvoid *zSrc = _mesa_image_address2d(unpack,
                                                      pixels, width, height,
                                                      GL_DEPTH_COMPONENT, type,
                                                      row, skipPixels);

            /* Set these for each row since the _swrast_write_* function may
             * change them while clipping.
             */
            span.x = spanX;
            span.y = spanY;
            span.end = spanEnd;

            _mesa_unpack_depth_span(ctx, span.end, floatSpan, type,
                                    zSrc, unpack);
            /* clamp depth values to [0,1] and convert from floats to ints */
            {
               GLuint i;
               for (i = 0; i < span.end; i++) {
                  span.array->z[i] = (GLdepth) (floatSpan[i] * depthMax);
               }
            }
            if (zoom) {
               _swrast_write_zoomed_depth_span(ctx, &span, desty, skipPixels);
            }
            else if (ctx->Visual.rgbMode) {
               _swrast_write_rgba_span(ctx, &span);
            }
            else {
               _swrast_write_index_span(ctx, &span);
            }
         }
         skipPixels += spanEnd;
      }
   }
}



/*
 * Draw RGBA image.
 */
static void
draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
                  GLsizei width, GLsizei height,
                  GLenum format, GLenum type,
                  const struct gl_pixelstore_attrib *unpack,
                  const GLvoid *pixels )
{
   struct gl_renderbuffer *rb = NULL; /* only used for quickDraw path */
   const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
   const GLint desty = y;
   GLboolean quickDraw;
   GLfloat *convImage = NULL;
   GLuint transferOps = ctx->_ImageTransferState;
   struct sw_span span;

   INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_RGBA);

   if (!_mesa_is_legal_format_and_type(ctx, format, type)) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glDrawPixels(format or type)");
      return;
   }

   /* Try an optimized glDrawPixels first */
   if (fast_draw_pixels(ctx, x, y, width, height, format, type, unpack, pixels))
      return;

   if (ctx->Depth.Test)
      _swrast_span_default_z(ctx, &span);
   if (ctx->Fog.Enabled)
      _swrast_span_default_fog(ctx, &span);
   if (ctx->Texture._EnabledCoordUnits)
      _swrast_span_default_texcoords(ctx, &span);

   if (SWRAST_CONTEXT(ctx)->_RasterMask == 0 && !zoom && x >= 0 && y >= 0
       && x + width <= (GLint) ctx->DrawBuffer->Width
       && y + height <= (GLint) ctx->DrawBuffer->Height
       && ctx->DrawBuffer->_NumColorDrawBuffers[0] == 1) {
      quickDraw = GL_TRUE;
      rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];
   }
   else {
      quickDraw = GL_FALSE;
      rb = NULL;
   }

   if (ctx->Pixel.Convolution2DEnabled || ctx->Pixel.Separable2DEnabled) {
      /* Convolution has to be handled specially.  We'll create an
       * intermediate image, applying all pixel transfer operations
       * up to convolution.  Then we'll convolve the image.  Then
       * we'll proceed with the rest of the transfer operations and
       * rasterize the image.
       */
      GLint row;
      GLfloat *dest, *tmpImage;

      tmpImage = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
      if (!tmpImage) {
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
         return;
      }
      convImage = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
      if (!convImage) {
         _mesa_free(tmpImage);
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
         return;
      }

      /* Unpack the image and apply transfer ops up to convolution */
      dest = tmpImage;
      for (row = 0; row < height; row++) {
         const GLvoid *source = _mesa_image_address2d(unpack,
                                  pixels, width, height, format, type, row, 0);
         _mesa_unpack_color_span_float(ctx, width, GL_RGBA, (GLfloat *) dest,
                                     format, type, source, unpack,
                                     transferOps & IMAGE_PRE_CONVOLUTION_BITS);
         dest += width * 4;
      }

      /* do convolution */
      if (ctx->Pixel.Convolution2DEnabled) {
         _mesa_convolve_2d_image(ctx, &width, &height, tmpImage, convImage);
      }
      else {
         ASSERT(ctx->Pixel.Separable2DEnabled);
         _mesa_convolve_sep_image(ctx, &width, &height, tmpImage, convImage);
      }
      _mesa_free(tmpImage);

      /* continue transfer ops and draw the convolved image */
      unpack = &ctx->DefaultPacking;
      pixels = convImage;
      format = GL_RGBA;
      type = GL_FLOAT;
      transferOps &= IMAGE_POST_CONVOLUTION_BITS;
   }

   /*
    * General solution
    */
   {
      const GLuint interpMask = span.interpMask;
      const GLuint arrayMask = span.arrayMask;
      GLint row, skipPixels = 0;

      /* if the span is wider than MAX_WIDTH we have to do it in chunks */
      while (skipPixels < width) {
         const GLint spanX = x + (zoom ? 0 : skipPixels);
         GLint spanY = y;
         const GLint spanEnd = (width - skipPixels > MAX_WIDTH)
                             ? MAX_WIDTH : (width - skipPixels);
         ASSERT(span.end <= MAX_WIDTH);

         for (row = 0; row < height; row++, spanY++) {
            const GLvoid *source = _mesa_image_address2d(unpack,
                     pixels, width, height, format, type, row, skipPixels);

            /* Set these for each row since the _swrast_write_* function may
             * change them while clipping.
             */
            span.x = spanX;
            span.y = spanY;
            span.end = spanEnd;
            span.arrayMask = arrayMask;
            span.interpMask = interpMask;

            _mesa_unpack_color_span_chan(ctx, span.end, GL_RGBA,
                                         (GLchan *) span.array->rgba,
                                         format, type, source, unpack,
                                         transferOps);

            if ((ctx->Pixel.MinMaxEnabled && ctx->MinMax.Sink) ||
                (ctx->Pixel.HistogramEnabled && ctx->Histogram.Sink))
               continue;

            if (ctx->Pixel.PixelTextureEnabled && ctx->Texture._EnabledUnits) {
               _swrast_pixel_texture(ctx, &span);
            }

            /* draw the span */
            if (quickDraw) {
               rb->PutRow(ctx, rb, span.end, span.x, span.y,
                          span.array->rgba, NULL);
            }
            else if (zoom) {
               _swrast_write_zoomed_rgba_span(ctx, &span,
                    (CONST GLchan (*)[4]) span.array->rgba, desty, skipPixels);
            }
            else {
               _swrast_write_rgba_span(ctx, &span);
            }
         }

         skipPixels += spanEnd;
      }
   }

   if (convImage) {
      _mesa_free(convImage);
   }
}



/*
 * Execute glDrawPixels
 */
void
_swrast_DrawPixels( GLcontext *ctx,
		    GLint x, GLint y,
		    GLsizei width, GLsizei height,
		    GLenum format, GLenum type,
		    const struct gl_pixelstore_attrib *unpack,
		    const GLvoid *pixels )
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);

   if (swrast->NewState)
      _swrast_validate_derived( ctx );

   if (unpack->BufferObj->Name) {
      /* unpack from PBO */
      GLubyte *buf;
      if (!_mesa_validate_pbo_access(2, unpack, width, height, 1,
                                     format, type, pixels)) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "glDrawPixels(invalid PBO access)");
         return;
      }
      buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
                                              GL_READ_ONLY_ARB,
                                              unpack->BufferObj);
      if (!buf) {
         /* buffer is already mapped - that's an error */
         _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels(PBO is mapped)");
         return;
      }
      pixels = ADD_POINTERS(buf, pixels);
   }

   RENDER_START(swrast,ctx);

   switch (format) {
   case GL_STENCIL_INDEX:
      draw_stencil_pixels( ctx, x, y, width, height, type, unpack, pixels );
      break;
   case GL_DEPTH_COMPONENT:
      draw_depth_pixels( ctx, x, y, width, height, type, unpack, pixels );
      break;
   case GL_COLOR_INDEX:
      if (ctx->Visual.rgbMode)
	 draw_rgba_pixels(ctx, x,y, width, height, format, type, unpack, pixels);
      else
	 draw_index_pixels(ctx, x, y, width, height, type, unpack, pixels);
      break;
   case GL_RED:
   case GL_GREEN:
   case GL_BLUE:
   case GL_ALPHA:
   case GL_LUMINANCE:
   case GL_LUMINANCE_ALPHA:
   case GL_RGB:
   case GL_BGR:
   case GL_RGBA:
   case GL_BGRA:
   case GL_ABGR_EXT:
      draw_rgba_pixels(ctx, x, y, width, height, format, type, unpack, pixels);
      break;
   default:
      _mesa_error( ctx, GL_INVALID_ENUM, "glDrawPixels(format)" );
      /* don't return yet, clean-up */
   }

   RENDER_FINISH(swrast,ctx);

   if (unpack->BufferObj->Name) {
      /* done with PBO so unmap it now */
      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
                              unpack->BufferObj);
   }
}



#if 0  /* experimental */
/*
 * Execute glDrawDepthPixelsMESA().
 */
void
_swrast_DrawDepthPixelsMESA( GLcontext *ctx,
                             GLint x, GLint y,
                             GLsizei width, GLsizei height,
                             GLenum colorFormat, GLenum colorType,
                             const GLvoid *colors,
                             GLenum depthType, const GLvoid *depths,
                             const struct gl_pixelstore_attrib *unpack )
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);

   if (swrast->NewState)
      _swrast_validate_derived( ctx );

   RENDER_START(swrast,ctx);

   switch (colorFormat) {
   case GL_COLOR_INDEX:
      if (ctx->Visual.rgbMode)
	 draw_rgba_pixels(ctx, x,y, width, height, colorFormat, colorType, unpack, colors);
      else
	 draw_index_pixels(ctx, x, y, width, height, colorType, unpack, colors);
      break;
   case GL_RED:
   case GL_GREEN:
   case GL_BLUE:
   case GL_ALPHA:
   case GL_LUMINANCE:
   case GL_LUMINANCE_ALPHA:
   case GL_RGB:
   case GL_BGR:
   case GL_RGBA:
   case GL_BGRA:
   case GL_ABGR_EXT:
      draw_rgba_pixels(ctx, x, y, width, height, colorFormat, colorType, unpack, colors);
      break;
   default:
      _mesa_error( ctx, GL_INVALID_ENUM,
                   "glDrawDepthPixelsMESA(colorFormat)" );
   }

   RENDER_FINISH(swrast,ctx);
}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -