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

📄 s_copypix.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 2 页
字号:
      overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,                                    ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);   }   else {      overlapping = GL_FALSE;   }   /* Determine if copy should be bottom-to-top or top-to-bottom */   if (!overlapping && srcy < desty) {      /* top-down  max-to-min */      sy = srcy + height - 1;      dy = desty + height - 1;      stepy = -1;   }   else {      /* bottom-up  min-to-max */      sy = srcy;      dy = desty;      stepy = 1;   }   if (overlapping) {      GLint ssy = sy;      tmpImage = (GLfloat *) _mesa_malloc(width * height * sizeof(GLfloat));      if (!tmpImage) {         _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" );         return;      }      p = tmpImage;      for (j = 0; j < height; j++, ssy += stepy) {         _swrast_read_depth_span_float(ctx, readRb, width, srcx, ssy, p);         p += width;      }      p = tmpImage;   }   else {      tmpImage = NULL;  /* silence compiler warning */      p = NULL;   }   for (j = 0; j < height; j++, sy += stepy, dy += stepy) {      GLfloat depth[MAX_WIDTH];      /* get depth values */      if (overlapping) {         _mesa_memcpy(depth, p, width * sizeof(GLfloat));         p += width;      }      else {         _swrast_read_depth_span_float(ctx, readRb, width, srcx, sy, depth);      }      /* apply scale and bias */      scale_and_bias_z(ctx, width, depth, span.array->z);      /* write depth values */      span.x = destx;      span.y = dy;      span.end = width;      if (fb->Visual.rgbMode) {         if (zoom)            _swrast_write_zoomed_depth_span(ctx, destx, desty, &span);         else            _swrast_write_rgba_span(ctx, &span);      }      else {         if (zoom)            _swrast_write_zoomed_depth_span(ctx, destx, desty, &span);         else            _swrast_write_index_span(ctx, &span);      }   }   if (overlapping)      _mesa_free(tmpImage);}static voidcopy_stencil_pixels( GLcontext *ctx, GLint srcx, GLint srcy,                     GLint width, GLint height,                     GLint destx, GLint desty ){   struct gl_framebuffer *fb = ctx->ReadBuffer;   struct gl_renderbuffer *rb = fb->_StencilBuffer;   GLint sy, dy, stepy;   GLint j;   GLstencil *p, *tmpImage;   const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;   GLint overlapping;   if (!rb) {      /* no readbuffer - OK */      return;   }   if (ctx->DrawBuffer == ctx->ReadBuffer) {      overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,                                    ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);   }   else {      overlapping = GL_FALSE;   }   /* Determine if copy should be bottom-to-top or top-to-bottom */   if (!overlapping && srcy < desty) {      /* top-down  max-to-min */      sy = srcy + height - 1;      dy = desty + height - 1;      stepy = -1;   }   else {      /* bottom-up  min-to-max */      sy = srcy;      dy = desty;      stepy = 1;   }   if (overlapping) {      GLint ssy = sy;      tmpImage = (GLstencil *) _mesa_malloc(width * height * sizeof(GLstencil));      if (!tmpImage) {         _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" );         return;      }      p = tmpImage;      for (j = 0; j < height; j++, ssy += stepy) {         _swrast_read_stencil_span( ctx, rb, width, srcx, ssy, p );         p += width;      }      p = tmpImage;   }   else {      tmpImage = NULL;  /* silence compiler warning */      p = NULL;   }   for (j = 0; j < height; j++, sy += stepy, dy += stepy) {      GLstencil stencil[MAX_WIDTH];      /* Get stencil values */      if (overlapping) {         _mesa_memcpy(stencil, p, width * sizeof(GLstencil));         p += width;      }      else {         _swrast_read_stencil_span( ctx, rb, width, srcx, sy, stencil );      }      _mesa_apply_stencil_transfer_ops(ctx, width, stencil);      /* Write stencil values */      if (zoom) {         _swrast_write_zoomed_stencil_span(ctx, destx, desty, width,                                           destx, dy, stencil);      }      else {         _swrast_write_stencil_span( ctx, width, destx, dy, stencil );      }   }   if (overlapping)      _mesa_free(tmpImage);}/** * This isn't terribly efficient.  If a driver really has combined * depth/stencil buffers the driver should implement an optimized * CopyPixels function. */static voidcopy_depth_stencil_pixels(GLcontext *ctx,                          const GLint srcX, const GLint srcY,                          const GLint width, const GLint height,                          const GLint destX, const GLint destY){   struct gl_renderbuffer *stencilReadRb, *depthReadRb, *depthDrawRb;   GLint sy, dy, stepy;   GLint j;   GLstencil *tempStencilImage = NULL, *stencilPtr = NULL;   GLfloat *tempDepthImage = NULL, *depthPtr = NULL;   const GLfloat depthScale = ctx->DrawBuffer->_DepthMaxF;   const GLuint stencilMask = ctx->Stencil.WriteMask[0];   const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;   const GLboolean scaleOrBias      = ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0;   GLint overlapping;   depthDrawRb = ctx->DrawBuffer->_DepthBuffer;   depthReadRb = ctx->ReadBuffer->_DepthBuffer;   stencilReadRb = ctx->ReadBuffer->_StencilBuffer;   ASSERT(depthDrawRb);   ASSERT(depthReadRb);   ASSERT(stencilReadRb);   if (ctx->DrawBuffer == ctx->ReadBuffer) {      overlapping = regions_overlap(srcX, srcY, destX, destY, width, height,                                    ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);   }   else {      overlapping = GL_FALSE;   }   /* Determine if copy should be bottom-to-top or top-to-bottom */   if (!overlapping && srcY < destY) {      /* top-down  max-to-min */      sy = srcY + height - 1;      dy = destY + height - 1;      stepy = -1;   }   else {      /* bottom-up  min-to-max */      sy = srcY;      dy = destY;      stepy = 1;   }   if (overlapping) {      GLint ssy = sy;      if (stencilMask != 0x0) {         tempStencilImage            = (GLstencil *) _mesa_malloc(width * height * sizeof(GLstencil));         if (!tempStencilImage) {            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels");            return;         }         /* get copy of stencil pixels */         stencilPtr = tempStencilImage;         for (j = 0; j < height; j++, ssy += stepy) {            _swrast_read_stencil_span(ctx, stencilReadRb,                                      width, srcX, ssy, stencilPtr);            stencilPtr += width;         }         stencilPtr = tempStencilImage;      }      if (ctx->Depth.Mask) {         tempDepthImage            = (GLfloat *) _mesa_malloc(width * height * sizeof(GLfloat));         if (!tempDepthImage) {            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels");            _mesa_free(tempStencilImage);            return;         }         /* get copy of depth pixels */         depthPtr = tempDepthImage;         for (j = 0; j < height; j++, ssy += stepy) {            _swrast_read_depth_span_float(ctx, depthReadRb,                                          width, srcX, ssy, depthPtr);            depthPtr += width;         }         depthPtr = tempDepthImage;      }   }   for (j = 0; j < height; j++, sy += stepy, dy += stepy) {      if (stencilMask != 0x0) {         GLstencil stencil[MAX_WIDTH];         /* Get stencil values */         if (overlapping) {            _mesa_memcpy(stencil, stencilPtr, width * sizeof(GLstencil));            stencilPtr += width;         }         else {            _swrast_read_stencil_span(ctx, stencilReadRb,                                      width, srcX, sy, stencil);         }         _mesa_apply_stencil_transfer_ops(ctx, width, stencil);         /* Write values */         if (zoom) {            _swrast_write_zoomed_stencil_span(ctx, destX, destY, width,                                              destX, dy, stencil);         }         else {            _swrast_write_stencil_span( ctx, width, destX, dy, stencil );         }      }      if (ctx->Depth.Mask) {         GLfloat depth[MAX_WIDTH];         GLuint zVals32[MAX_WIDTH];         GLushort zVals16[MAX_WIDTH];         GLvoid *zVals;         GLuint zBytes;         /* get depth values */         if (overlapping) {            _mesa_memcpy(depth, depthPtr, width * sizeof(GLfloat));            depthPtr += width;         }         else {            _swrast_read_depth_span_float(ctx, depthReadRb,                                          width, srcX, sy, depth);         }         /* scale & bias */         if (scaleOrBias) {            _mesa_scale_and_bias_depth(ctx, width, depth);         }         /* convert to integer Z values */         if (depthDrawRb->DataType == GL_UNSIGNED_SHORT) {            GLint k;            for (k = 0; k < width; k++)               zVals16[k] = (GLushort) (depth[k] * depthScale);            zVals = zVals16;            zBytes = 2;         }         else {            GLint k;            for (k = 0; k < width; k++)               zVals32[k] = (GLuint) (depth[k] * depthScale);            zVals = zVals32;            zBytes = 4;         }         /* Write values */         if (zoom) {            _swrast_write_zoomed_z_span(ctx, destX, destY, width,                                        destX, dy, zVals);         }         else {            _swrast_put_row(ctx, depthDrawRb, width, destX, dy, zVals, zBytes);         }      }   }   if (tempStencilImage)      _mesa_free(tempStencilImage);   if (tempDepthImage)      _mesa_free(tempDepthImage);}/** * Try to do a fast copy pixels. */static GLbooleanfast_copy_pixels(GLcontext *ctx,                 GLint srcX, GLint srcY, GLsizei width, GLsizei height,                 GLint dstX, GLint dstY, GLenum type){   struct gl_framebuffer *srcFb = ctx->ReadBuffer;   struct gl_framebuffer *dstFb = ctx->DrawBuffer;   struct gl_renderbuffer *srcRb, *dstRb;   GLint row, yStep;   if (SWRAST_CONTEXT(ctx)->_RasterMask != 0x0 ||       ctx->Pixel.ZoomX != 1.0F ||       ctx->Pixel.ZoomY != 1.0F ||       ctx->_ImageTransferState) {      /* can't handle these */      return GL_FALSE;   }   if (type == GL_COLOR) {      if (dstFb->_NumColorDrawBuffers != 1)         return GL_FALSE;      srcRb = srcFb->_ColorReadBuffer;      dstRb = dstFb->_ColorDrawBuffers[0];   }   else if (type == GL_STENCIL) {      srcRb = srcFb->_StencilBuffer;      dstRb = dstFb->_StencilBuffer;   }   else if (type == GL_DEPTH) {      srcRb = srcFb->_DepthBuffer;      dstRb = dstFb->_DepthBuffer;   }   else {      ASSERT(type == GL_DEPTH_STENCIL_EXT);      /* XXX correct? */      srcRb = srcFb->Attachment[BUFFER_DEPTH].Renderbuffer;      dstRb = dstFb->Attachment[BUFFER_DEPTH].Renderbuffer;   }   /* src and dst renderbuffers must be same format and type */   if (!srcRb || !dstRb ||       srcRb->DataType != dstRb->DataType ||       srcRb->_BaseFormat != dstRb->_BaseFormat) {      return GL_FALSE;   }   /* clipping not supported */   if (srcX < 0 || srcX + width > (GLint) srcFb->Width ||       srcY < 0 || srcY + height > (GLint) srcFb->Height ||       dstX < dstFb->_Xmin || dstX + width > dstFb->_Xmax ||       dstY < dstFb->_Ymin || dstY + height > dstFb->_Ymax) {      return GL_FALSE;   }   /* overlapping src/dst doesn't matter, just determine Y direction */   if (srcY < dstY) {      /* top-down  max-to-min */      srcY = srcY + height - 1;      dstY = dstY + height - 1;      yStep = -1;   }   else {      /* bottom-up  min-to-max */      yStep = 1;   }   for (row = 0; row < height; row++) {      GLuint temp[MAX_WIDTH][4];      srcRb->GetRow(ctx, srcRb, width, srcX, srcY, temp);      dstRb->PutRow(ctx, dstRb, width, dstX, dstY, temp, NULL);      srcY += yStep;      dstY += yStep;   }   return GL_TRUE;}/** * Do software-based glCopyPixels. * By time we get here, all parameters will have been error-checked. */void_swrast_CopyPixels( GLcontext *ctx,		    GLint srcx, GLint srcy, GLsizei width, GLsizei height,		    GLint destx, GLint desty, GLenum type ){   SWcontext *swrast = SWRAST_CONTEXT(ctx);   RENDER_START(swrast,ctx);         if (swrast->NewState)      _swrast_validate_derived( ctx );   if (!fast_copy_pixels(ctx, srcx, srcy, width, height, destx, desty, type)) {      switch (type) {      case GL_COLOR:         if (ctx->Visual.rgbMode) {            copy_rgba_pixels( ctx, srcx, srcy, width, height, destx, desty );         }         else {            copy_ci_pixels( ctx, srcx, srcy, width, height, destx, desty );         }         break;      case GL_DEPTH:         copy_depth_pixels( ctx, srcx, srcy, width, height, destx, desty );         break;      case GL_STENCIL:         copy_stencil_pixels( ctx, srcx, srcy, width, height, destx, desty );         break;      case GL_DEPTH_STENCIL_EXT:         copy_depth_stencil_pixels(ctx, srcx, srcy, width, height, destx, desty);         break;      default:         _mesa_problem(ctx, "unexpected type in _swrast_CopyPixels");      }   }   RENDER_FINISH(swrast,ctx);}

⌨️ 快捷键说明

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