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

📄 s_drawpix.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Mesa 3-D graphics library * Version:  7.1 * * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */#include "glheader.h"#include "bufferobj.h"#include "context.h"#include "convolve.h"#include "image.h"#include "macros.h"#include "imports.h"#include "pixel.h"#include "state.h"#include "s_context.h"#include "s_drawpix.h"#include "s_span.h"#include "s_stencil.h"#include "s_zoom.h"/** * Try to do a fast and simple RGB(a) glDrawPixels. * Return:  GL_TRUE if success, GL_FALSE if slow path must be used instead */static GLbooleanfast_draw_rgba_pixels(GLcontext *ctx, GLint x, GLint y,                      GLsizei width, GLsizei height,                      GLenum format, GLenum type,                      const struct gl_pixelstore_attrib *userUnpack,                      const GLvoid *pixels){   const GLint imgX = x, imgY = y;   struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];   GLenum rbType;   SWcontext *swrast = SWRAST_CONTEXT(ctx);   SWspan span;   GLboolean simpleZoom;   GLint yStep;  /* +1 or -1 */   struct gl_pixelstore_attrib unpack;   GLint destX, destY, drawWidth, drawHeight; /* post clipping */   if (!rb)      return GL_TRUE; /* no-op */   rbType = rb->DataType;   if ((swrast->_RasterMask & ~CLIP_BIT) ||       ctx->Texture._EnabledCoordUnits ||       userUnpack->SwapBytes ||       ctx->_ImageTransferState) {      /* can't handle any of those conditions */      return GL_FALSE;   }   INIT_SPAN(span, GL_BITMAP);   span.arrayMask = SPAN_RGBA;   span.arrayAttribs = FRAG_BIT_COL0;   _swrast_span_default_attribs(ctx, &span);   /* copy input params since clipping may change them */   unpack = *userUnpack;   destX = x;   destY = y;   drawWidth = width;   drawHeight = height;   /* check for simple zooming and clipping */   if (ctx->Pixel.ZoomX == 1.0F &&       (ctx->Pixel.ZoomY == 1.0F || ctx->Pixel.ZoomY == -1.0F)) {      if (!_mesa_clip_drawpixels(ctx, &destX, &destY,                                 &drawWidth, &drawHeight, &unpack)) {         /* image was completely clipped: no-op, all done */         return GL_TRUE;      }      simpleZoom = GL_TRUE;      yStep = (GLint) ctx->Pixel.ZoomY;      ASSERT(yStep == 1 || yStep == -1);   }   else {      /* non-simple zooming */      simpleZoom = GL_FALSE;      yStep = 1;      if (unpack.RowLength == 0)         unpack.RowLength = width;   }   /*    * Ready to draw!    */   if (format == GL_RGBA && type == rbType) {      const GLubyte *src         = (const GLubyte *) _mesa_image_address2d(&unpack, pixels, width,                                                   height, format, type, 0, 0);      const GLint srcStride = _mesa_image_row_stride(&unpack, width,                                                     format, type);      if (simpleZoom) {         GLint row;         for (row = 0; row < drawHeight; row++) {            rb->PutRow(ctx, rb, drawWidth, destX, destY, src, NULL);            src += srcStride;            destY += yStep;         }      }      else {         /* with zooming */         GLint row;         for (row = 0; row < drawHeight; row++) {            span.x = destX;            span.y = destY + row;            span.end = drawWidth;            span.array->ChanType = rbType;            _swrast_write_zoomed_rgba_span(ctx, imgX, imgY, &span, src);            src += srcStride;         }         span.array->ChanType = CHAN_TYPE;      }      return GL_TRUE;   }   if (format == GL_RGB && type == rbType) {      const GLubyte *src         = (const GLubyte *) _mesa_image_address2d(&unpack, pixels, width,                                                   height, format, type, 0, 0);      const GLint srcStride = _mesa_image_row_stride(&unpack, width,                                                     format, type);      if (simpleZoom) {         GLint row;         for (row = 0; row < drawHeight; row++) {            rb->PutRowRGB(ctx, rb, drawWidth, destX, destY, src, NULL);            src += srcStride;            destY += yStep;         }      }      else {         /* with zooming */         GLint row;         for (row = 0; row < drawHeight; row++) {            span.x = destX;            span.y = destY;            span.end = drawWidth;            span.array->ChanType = rbType;            _swrast_write_zoomed_rgb_span(ctx, imgX, imgY, &span, src);            src += srcStride;            destY++;         }         span.array->ChanType = CHAN_TYPE;      }      return GL_TRUE;   }   /* Remaining cases haven't been tested with alignment != 1 */   if (userUnpack->Alignment != 1)      return GL_FALSE;   if (format == GL_LUMINANCE && type == CHAN_TYPE && rbType == CHAN_TYPE) {      const GLchan *src = (const GLchan *) pixels         + (unpack.SkipRows * unpack.RowLength + unpack.SkipPixels);      if (simpleZoom) {         /* no zooming */         GLint row;         ASSERT(drawWidth <= MAX_WIDTH);         for (row = 0; row < drawHeight; row++) {            GLchan rgb[MAX_WIDTH][3];            GLint i;            for (i = 0;i<drawWidth;i++) {               rgb[i][0] = src[i];               rgb[i][1] = src[i];               rgb[i][2] = src[i];            }            rb->PutRowRGB(ctx, rb, drawWidth, destX, destY, rgb, NULL);            src += unpack.RowLength;            destY += yStep;         }      }      else {         /* with zooming */         GLint row;         ASSERT(drawWidth <= MAX_WIDTH);         for (row = 0; row < drawHeight; row++) {            GLchan rgb[MAX_WIDTH][3];            GLint i;            for (i = 0;i<drawWidth;i++) {               rgb[i][0] = src[i];               rgb[i][1] = src[i];               rgb[i][2] = src[i];            }            span.x = destX;            span.y = destY;            span.end = drawWidth;            _swrast_write_zoomed_rgb_span(ctx, imgX, imgY, &span, rgb);            src += unpack.RowLength;            destY++;         }      }      return GL_TRUE;   }   if (format == GL_LUMINANCE_ALPHA && type == CHAN_TYPE && rbType == CHAN_TYPE) {      const GLchan *src = (const GLchan *) pixels         + (unpack.SkipRows * unpack.RowLength + unpack.SkipPixels)*2;      if (simpleZoom) {         GLint row;         ASSERT(drawWidth <= MAX_WIDTH);         for (row = 0; row < drawHeight; row++) {            GLint i;            const GLchan *ptr = src;            for (i = 0;i<drawWidth;i++) {               span.array->rgba[i][0] = *ptr;               span.array->rgba[i][1] = *ptr;               span.array->rgba[i][2] = *ptr++;               span.array->rgba[i][3] = *ptr++;            }            rb->PutRow(ctx, rb, drawWidth, destX, destY,                       span.array->rgba, NULL);            src += unpack.RowLength*2;            destY += yStep;         }      }      else {         /* with zooming */         GLint row;         ASSERT(drawWidth <= MAX_WIDTH);         for (row = 0; row < drawHeight; row++) {            const GLchan *ptr = src;            GLint i;            for (i = 0;i<drawWidth;i++) {               span.array->rgba[i][0] = *ptr;               span.array->rgba[i][1] = *ptr;               span.array->rgba[i][2] = *ptr++;               span.array->rgba[i][3] = *ptr++;            }            span.x = destX;            span.y = destY;            span.end = drawWidth;            _swrast_write_zoomed_rgba_span(ctx, imgX, imgY, &span,                                           span.array->rgba);            src += unpack.RowLength*2;            destY++;         }      }      return GL_TRUE;   }   if (format == GL_COLOR_INDEX && type == GL_UNSIGNED_BYTE) {      const GLubyte *src = (const GLubyte *) pixels         + unpack.SkipRows * unpack.RowLength + unpack.SkipPixels;      if (ctx->Visual.rgbMode && rbType == GL_UNSIGNED_BYTE) {         /* convert ubyte/CI data to ubyte/RGBA */         if (simpleZoom) {            GLint row;            for (row = 0; row < drawHeight; row++) {               ASSERT(drawWidth <= MAX_WIDTH);               _mesa_map_ci8_to_rgba8(ctx, drawWidth, src,                                      span.array->rgba8);               rb->PutRow(ctx, rb, drawWidth, destX, destY,                          span.array->rgba8, NULL);               src += unpack.RowLength;               destY += yStep;            }         }         else {            /* ubyte/CI to ubyte/RGBA with zooming */            GLint row;            for (row = 0; row < drawHeight; row++) {               ASSERT(drawWidth <= MAX_WIDTH);               _mesa_map_ci8_to_rgba8(ctx, drawWidth, src,                                      span.array->rgba8);               span.x = destX;               span.y = destY;               span.end = drawWidth;               _swrast_write_zoomed_rgba_span(ctx, imgX, imgY, &span,                                              span.array->rgba8);               src += unpack.RowLength;               destY++;            }         }         return GL_TRUE;      }      else if (!ctx->Visual.rgbMode && rbType == GL_UNSIGNED_INT) {         /* write CI data to CI frame buffer */         GLint row;         if (simpleZoom) {            for (row = 0; row < drawHeight; row++) {               GLuint index32[MAX_WIDTH];               GLint col;               for (col = 0; col < drawWidth; col++)                  index32[col] = src[col];               rb->PutRow(ctx, rb, drawWidth, destX, destY, index32, NULL);               src += unpack.RowLength;               destY += yStep;

⌨️ 快捷键说明

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