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

📄 s_zoom.c

📁 mesa-6.5-minigui源码
💻 C
字号:
/* * Mesa 3-D graphics library * Version:  6.5 * * Copyright (C) 1999-2005  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 "macros.h"#include "imports.h"#include "colormac.h"#include "s_context.h"#include "s_span.h"#include "s_stencil.h"#include "s_zoom.h"/** * Compute the bounds of the region resulting from zooming a pixel span. * The resulting region will be entirely inside the window/scissor bounds * so no additional clipping is needed. * \param imageX, imageY  position of the overall image being drawn * \param spanX, spanY  position of span being drawing * \param x0, x1  returned X bounds of zoomed region [x0, x1) * \param y0, y1  returned Y bounds of zoomed region [y0, y1) * \return GL_TRUE if any zoomed pixels visible, GL_FALSE if totally clipped */static GLbooleancompute_zoomed_bounds(GLcontext *ctx, GLint imageX, GLint imageY,                      GLint spanX, GLint spanY, GLint width,                      GLint *x0, GLint *x1, GLint *y0, GLint *y1){   const struct gl_framebuffer *fb = ctx->DrawBuffer;   GLint c0, c1, r0, r1;   ASSERT(spanX >= imageX);   ASSERT(spanY >= imageY);   /*    * Compute destination columns: [c0, c1)    */   c0 = imageX + (GLint) ((spanX - imageX) * ctx->Pixel.ZoomX);   c1 = imageX + (GLint) ((spanX + width - imageX) * ctx->Pixel.ZoomX);   if (c1 < c0) {      /* swap */      GLint tmp = c1;      c1 = c0;      c0 = tmp;   }   c0 = CLAMP(c0, fb->_Xmin, fb->_Xmax);   c1 = CLAMP(c1, fb->_Xmin, fb->_Xmax);   if (c0 == c1) {      return GL_FALSE; /* no width */   }   /*    * Compute destination rows: [r0, r1)    */   r0 = imageY + (GLint) ((spanY - imageY) * ctx->Pixel.ZoomY);   r1 = imageY + (GLint) ((spanY + 1 - imageY) * ctx->Pixel.ZoomY);   if (r1 < r0) {      /* swap */      GLint tmp = r1;      r1 = r0;      r0 = tmp;   }   r0 = CLAMP(r0, fb->_Ymin, fb->_Ymax);   r1 = CLAMP(r1, fb->_Ymin, fb->_Ymax);   if (r0 == r1) {      return GL_FALSE; /* no height */   }   *x0 = c0;   *x1 = c1;   *y0 = r0;   *y1 = r1;   return GL_TRUE;}/** * Can use this for unzooming X or Y values. */static INLINE GLintunzoom_x(GLfloat zoomX, GLint imageX, GLint zx){   /*   zx = imageX + (x - imageX) * zoomX;   zx - imageX = (x - imageX) * zoomX;   (zx - imageX) / zoomX = x - imageX;   */   GLint x = imageX + (GLint) ((zx - imageX) / zoomX);   return x;}/** * Helper function called from _swrast_write_zoomed_rgba/rgb/ * index/depth_span(). */static voidzoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const struct sw_span *span,           const GLvoid *src, GLenum format ){   struct sw_span zoomed;   struct span_arrays zoomed_arrays;  /* this is big! */   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 */   }   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, 0, 0, 0);   zoomed.x = x0;   zoomed.end = zoomedWidth;   zoomed.array = &zoomed_arrays;   /* copy fog interp info */   zoomed.fog = span->fog;   zoomed.fogStep = span->fogStep;   /* XXX copy texcoord info? */   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;      ASSERT(span->arrayMask & SPAN_RGBA);   }   else if (format == GL_COLOR_INDEX) {      /* copy Z info */      zoomed.z = span->z;      zoomed.zStep = span->zStep;      /* we'll generate an array of color indexes */      zoomed.interpMask = span->interpMask & ~SPAN_INDEX;      zoomed.arrayMask |= SPAN_INDEX;      ASSERT(span->arrayMask & SPAN_INDEX);   }   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) {      const GLchan (*rgba)[4] = (const GLchan (*)[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_CHAN4(zoomed.array->rgba[i], rgba[j]);      }   }   else if (format == GL_RGB) {      const GLchan (*rgb)[3] = (const GLchan (*)[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->rgba[i][0] = rgb[j][0];         zoomed.array->rgba[i][1] = rgb[j][1];         zoomed.array->rgba[i][2] = rgb[j][2];         zoomed.array->rgba[i][3] = CHAN_MAX;      }   }   else if (format == GL_COLOR_INDEX) {      const GLuint *indexes = (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 < span->end);         zoomed.array->index[i] = indexes[j];      }   }   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 < span->end);         zoomed.array->z[i] = zValues[j];      }      /* Now, fall into either the RGB or COLOR_INDEX path below */      format = ctx->Visual.rgbMode ? GL_RGBA : GL_COLOR_INDEX;   }   /* 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.       */      GLchan rgbaSave[MAX_WIDTH][4];      const GLint end = zoomed.end; /* save */      if (y1 - y0 > 1) {         MEMCPY(rgbaSave, zoomed.array->rgba, zoomed.end * 4 * sizeof(GLchan));      }      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*4 * sizeof(GLchan));         }      }   }   else if (format == GL_COLOR_INDEX) {      GLuint indexSave[MAX_WIDTH];      const GLint end = zoomed.end; /* save */      if (y1 - y0 > 1) {         MEMCPY(indexSave, zoomed.array->index, zoomed.end * sizeof(GLuint));      }      for (zoomed.y = y0; zoomed.y < y1; zoomed.y++) {         _swrast_write_index_span(ctx, &zoomed);         zoomed.end = end;  /* restore */         if (y1 - y0 > 1) {            /* restore the colors */            MEMCPY(zoomed.array->index, indexSave, zoomed.end * sizeof(GLuint));         }      }   }}void_swrast_write_zoomed_rgba_span( GLcontext *ctx, GLint imgX, GLint imgY,                               const struct sw_span *span,                               CONST GLchan rgba[][4]){   zoom_span(ctx, imgX, imgY, span, (const GLvoid *) rgba, GL_RGBA);}void_swrast_write_zoomed_rgb_span(GLcontext *ctx, GLint imgX, GLint imgY,                              const struct sw_span *span,                              CONST GLchan rgb[][3]){   zoom_span(ctx, imgX, imgY, span, (const GLvoid *) rgb, GL_RGB);}void_swrast_write_zoomed_index_span(GLcontext *ctx, GLint imgX, GLint imgY,                                const struct sw_span *span){   zoom_span(ctx, imgX, imgY, span,             (const GLvoid *) span->array->index, GL_COLOR_INDEX);}void_swrast_write_zoomed_depth_span(GLcontext *ctx, GLint imgX, GLint imgY,                                const struct sw_span *span){   zoom_span(ctx, imgX, imgY, span,             (const GLvoid *) span->array->z, GL_DEPTH_COMPONENT);}/** * Zoom/write stencil values. * No per-fragment operations are applied. */void_swrast_write_zoomed_stencil_span(GLcontext *ctx, GLint imgX, GLint imgY,                                  GLint width, GLint spanX, GLint spanY,                                  const GLstencil stencil[]){   GLstencil zoomedVals[MAX_WIDTH];   GLint x0, x1, y0, y1, y;   GLint i, zoomedWidth;   if (!compute_zoomed_bounds(ctx, imgX, imgY, spanX, spanY, width,                              &x0, &x1, &y0, &y1)) {      return;  /* totally clipped */   }   zoomedWidth = x1 - x0;   ASSERT(zoomedWidth > 0);   ASSERT(zoomedWidth <= MAX_WIDTH);   /* zoom the span horizontally */   for (i = 0; i < zoomedWidth; i++) {      GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - spanX;      ASSERT(j >= 0);      ASSERT(j < width);      zoomedVals[i] = stencil[j];   }   /* write the zoomed spans */   for (y = y0; y < y1; y++) {      _swrast_write_stencil_span(ctx, zoomedWidth, x0, y, zoomedVals);   }}/** * Zoom/write z values (16 or 32-bit). * No per-fragment operations are applied. */void_swrast_write_zoomed_z_span(GLcontext *ctx, GLint imgX, GLint imgY,                            GLint width, GLint spanX, GLint spanY,                            const GLvoid *z){   struct gl_renderbuffer *rb = ctx->DrawBuffer->_DepthBuffer;   GLushort zoomedVals16[MAX_WIDTH];   GLuint zoomedVals32[MAX_WIDTH];   GLint x0, x1, y0, y1, y;   GLint i, zoomedWidth;   if (!compute_zoomed_bounds(ctx, imgX, imgY, spanX, spanY, width,                              &x0, &x1, &y0, &y1)) {      return;  /* totally clipped */   }   zoomedWidth = x1 - x0;   ASSERT(zoomedWidth > 0);   ASSERT(zoomedWidth <= MAX_WIDTH);   /* zoom the span horizontally */   if (rb->DataType == GL_UNSIGNED_SHORT) {      for (i = 0; i < zoomedWidth; i++) {         GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - spanX;         ASSERT(j >= 0);         ASSERT(j < width);         zoomedVals16[i] = ((GLushort *) z)[j];      }      z = zoomedVals16;   }   else {      ASSERT(rb->DataType == GL_UNSIGNED_INT);      for (i = 0; i < zoomedWidth; i++) {         GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - spanX;         ASSERT(j >= 0);         ASSERT(j < width);         zoomedVals32[i] = ((GLuint *) z)[j];      }      z = zoomedVals32;   }   /* write the zoomed spans */   for (y = y0; y < y1; y++) {      rb->PutRow(ctx, rb, zoomedWidth, x0, y, z, NULL);   }}

⌨️ 快捷键说明

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