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

📄 s_span.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 4 页
字号:
   }   /* Stencil and Z testing */   if (ctx->Stencil.Enabled || ctx->Depth.Test) {      if (!(span->arrayMask & SPAN_Z))         _swrast_span_interpolate_z(ctx, span);      if (ctx->Stencil.Enabled && fb->Visual.stencilBits > 0) {         /* Combined Z/stencil tests */         if (!_swrast_stencil_and_ztest_span(ctx, span)) {            goto end;         }      }      else if (fb->Visual.depthBits > 0) {         /* Just regular depth testing */         ASSERT(ctx->Depth.Test);         ASSERT(span->arrayMask & SPAN_Z);         if (!_swrast_depth_test_span(ctx, span)) {            goto end;         }      }   }#if FEATURE_ARB_occlusion_query   if (ctx->Query.CurrentOcclusionObject) {      /* update count of 'passed' fragments */      struct gl_query_object *q = ctx->Query.CurrentOcclusionObject;      GLuint i;      for (i = 0; i < span->end; i++)         q->Result += span->array->mask[i];   }#endif   /* We had to wait until now to check for glColorMask(0,0,0,0) because of    * the occlusion test.    */   if (colorMask == 0x0) {      goto end;   }   /* If we were able to defer fragment color computation to now, there's    * a good chance that many fragments will have already been killed by    * Z/stencil testing.    */   if (shaderOrTexture && swrast->_DeferredTexture) {      shade_texture_span(ctx, span);   }#if CHAN_BITS == 32   if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) {      interpolate_active_attribs(ctx, span, FRAG_BIT_COL0);   }#else   if ((span->arrayMask & SPAN_RGBA) == 0) {      interpolate_int_colors(ctx, span);   }#endif   ASSERT(span->arrayMask & SPAN_RGBA);   if (!shader) {      /* Add base and specular colors */      if (ctx->Fog.ColorSumEnabled ||          (ctx->Light.Enabled &&           ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) {         add_specular(ctx, span);      }   }   /* Fog */   if (swrast->_FogEnabled) {      _swrast_fog_rgba_span(ctx, span);   }   /* Antialias coverage application */   if (span->arrayMask & SPAN_COVERAGE) {      apply_aa_coverage(span);   }   /* Clamp color/alpha values over the range [0.0, 1.0] before storage */   if (ctx->Color.ClampFragmentColor == GL_TRUE &&       span->array->ChanType == GL_FLOAT) {      clamp_colors(span);   }   /*    * Write to renderbuffers    */   {      const GLuint numBuffers = fb->_NumColorDrawBuffers;      const GLboolean multiFragOutputs = numBuffers > 1;      GLuint buf;      for (buf = 0; buf < numBuffers; buf++) {         struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[buf];         /* color[fragOutput] will be written to buffer[buf] */         if (rb) {            GLchan rgbaSave[MAX_WIDTH][4];            const GLuint fragOutput = multiFragOutputs ? buf : 0;            if (rb->DataType != span->array->ChanType || fragOutput > 0) {               convert_color_type(span, rb->DataType, fragOutput);            }            if (!multiFragOutputs && numBuffers > 1) {               /* save colors for second, third renderbuffer writes */               _mesa_memcpy(rgbaSave, span->array->rgba,                            4 * span->end * sizeof(GLchan));            }            ASSERT(rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB);            if (ctx->Color._LogicOpEnabled) {               _swrast_logicop_rgba_span(ctx, rb, span);            }            else if (ctx->Color.BlendEnabled) {               _swrast_blend_span(ctx, rb, span);            }            if (colorMask != 0xffffffff) {               _swrast_mask_rgba_span(ctx, rb, span);            }            if (span->arrayMask & SPAN_XY) {               /* array of pixel coords */               ASSERT(rb->PutValues);               rb->PutValues(ctx, rb, span->end,                             span->array->x, span->array->y,                             span->array->rgba, span->array->mask);            }            else {               /* horizontal run of pixels */               ASSERT(rb->PutRow);               rb->PutRow(ctx, rb, span->end, span->x, span->y,                          span->array->rgba,                          span->writeAll ? NULL: span->array->mask);            }            if (!multiFragOutputs && numBuffers > 1) {               /* restore original span values */               _mesa_memcpy(span->array->rgba, rgbaSave,                            4 * span->end * sizeof(GLchan));            }         } /* if rb */      } /* for buf */   }end:   /* restore these values before returning */   span->interpMask = origInterpMask;   span->arrayMask = origArrayMask;   span->arrayAttribs = origArrayAttribs;   span->array->ChanType = origChanType;   span->array->rgba = origRgba;}/** * Read RGBA pixels from a renderbuffer.  Clipping will be done to prevent * reading ouside the buffer's boundaries. * \param dstType  datatype for returned colors * \param rgba  the returned colors */void_swrast_read_rgba_span( GLcontext *ctx, struct gl_renderbuffer *rb,                        GLuint n, GLint x, GLint y, GLenum dstType,                        GLvoid *rgba){   const GLint bufWidth = (GLint) rb->Width;   const GLint bufHeight = (GLint) rb->Height;   if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) {      /* completely above, below, or right */      /* XXX maybe leave rgba values undefined? */      _mesa_bzero(rgba, 4 * n * sizeof(GLchan));   }   else {      GLint skip, length;      if (x < 0) {         /* left edge clipping */         skip = -x;         length = (GLint) n - skip;         if (length < 0) {            /* completely left of window */            return;         }         if (length > bufWidth) {            length = bufWidth;         }      }      else if ((GLint) (x + n) > bufWidth) {         /* right edge clipping */         skip = 0;         length = bufWidth - x;         if (length < 0) {            /* completely to right of window */            return;         }      }      else {         /* no clipping */         skip = 0;         length = (GLint) n;      }      ASSERT(rb);      ASSERT(rb->GetRow);      ASSERT(rb->_BaseFormat == GL_RGB || rb->_BaseFormat == GL_RGBA);      if (rb->DataType == dstType) {         rb->GetRow(ctx, rb, length, x + skip, y,                    (GLubyte *) rgba + skip * RGBA_PIXEL_SIZE(rb->DataType));      }      else {         GLuint temp[MAX_WIDTH * 4];         rb->GetRow(ctx, rb, length, x + skip, y, temp);         _mesa_convert_colors(rb->DataType, temp,                   dstType, (GLubyte *) rgba + skip * RGBA_PIXEL_SIZE(dstType),                   length, NULL);      }   }}/** * Read CI pixels from a renderbuffer.  Clipping will be done to prevent * reading ouside the buffer's boundaries. */void_swrast_read_index_span( GLcontext *ctx, struct gl_renderbuffer *rb,                         GLuint n, GLint x, GLint y, GLuint index[] ){   const GLint bufWidth = (GLint) rb->Width;   const GLint bufHeight = (GLint) rb->Height;   if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) {      /* completely above, below, or right */      _mesa_bzero(index, n * sizeof(GLuint));   }   else {      GLint skip, length;      if (x < 0) {         /* left edge clipping */         skip = -x;         length = (GLint) n - skip;         if (length < 0) {            /* completely left of window */            return;         }         if (length > bufWidth) {            length = bufWidth;         }      }      else if ((GLint) (x + n) > bufWidth) {         /* right edge clipping */         skip = 0;         length = bufWidth - x;         if (length < 0) {            /* completely to right of window */            return;         }      }      else {         /* no clipping */         skip = 0;         length = (GLint) n;      }      ASSERT(rb->GetRow);      ASSERT(rb->_BaseFormat == GL_COLOR_INDEX);      if (rb->DataType == GL_UNSIGNED_BYTE) {         GLubyte index8[MAX_WIDTH];         GLint i;         rb->GetRow(ctx, rb, length, x + skip, y, index8);         for (i = 0; i < length; i++)            index[skip + i] = index8[i];      }      else if (rb->DataType == GL_UNSIGNED_SHORT) {         GLushort index16[MAX_WIDTH];         GLint i;         rb->GetRow(ctx, rb, length, x + skip, y, index16);         for (i = 0; i < length; i++)            index[skip + i] = index16[i];      }      else if (rb->DataType == GL_UNSIGNED_INT) {         rb->GetRow(ctx, rb, length, x + skip, y, index + skip);      }   }}/** * Wrapper for gl_renderbuffer::GetValues() which does clipping to avoid * reading values outside the buffer bounds. * We can use this for reading any format/type of renderbuffer. * \param valueSize is the size in bytes of each value (pixel) put into the *                  values array. */void_swrast_get_values(GLcontext *ctx, struct gl_renderbuffer *rb,                   GLuint count, const GLint x[], const GLint y[],                   void *values, GLuint valueSize){   GLuint i, inCount = 0, inStart = 0;   for (i = 0; i < count; i++) {      if (x[i] >= 0 && y[i] >= 0 &&	  x[i] < (GLint) rb->Width && y[i] < (GLint) rb->Height) {         /* inside */         if (inCount == 0)            inStart = i;         inCount++;      }      else {         if (inCount > 0) {            /* read [inStart, inStart + inCount) */            rb->GetValues(ctx, rb, inCount, x + inStart, y + inStart,                          (GLubyte *) values + inStart * valueSize);            inCount = 0;         }      }   }   if (inCount > 0) {      /* read last values */      rb->GetValues(ctx, rb, inCount, x + inStart, y + inStart,                    (GLubyte *) values + inStart * valueSize);   }}/** * Wrapper for gl_renderbuffer::PutRow() which does clipping. * \param valueSize  size of each value (pixel) in bytes */void_swrast_put_row(GLcontext *ctx, struct gl_renderbuffer *rb,                GLuint count, GLint x, GLint y,                const GLvoid *values, GLuint valueSize){   GLint skip = 0;   if (y < 0 || y >= (GLint) rb->Height)      return; /* above or below */   if (x + (GLint) count <= 0 || x >= (GLint) rb->Width)      return; /* entirely left or right */   if ((GLint) (x + count) > (GLint) rb->Width) {      /* right clip */      GLint clip = x + count - rb->Width;      count -= clip;   }   if (x < 0) {      /* left clip */      skip = -x;      x = 0;      count -= skip;   }   rb->PutRow(ctx, rb, count, x, y,              (const GLubyte *) values + skip * valueSize, NULL);}/** * Wrapper for gl_renderbuffer::GetRow() which does clipping. * \param valueSize  size of each value (pixel) in bytes */void_swrast_get_row(GLcontext *ctx, struct gl_renderbuffer *rb,                GLuint count, GLint x, GLint y,                GLvoid *values, GLuint valueSize){   GLint skip = 0;   if (y < 0 || y >= (GLint) rb->Height)      return; /* above or below */   if (x + (GLint) count <= 0 || x >= (GLint) rb->Width)      return; /* entirely left or right */   if (x + count > rb->Width) {      /* right clip */      GLint clip = x + count - rb->Width;      count -= clip;   }   if (x < 0) {      /* left clip */      skip = -x;      x = 0;      count -= skip;   }   rb->GetRow(ctx, rb, count, x, y, (GLubyte *) values + skip * valueSize);}/** * Get RGBA pixels from the given renderbuffer.  Put the pixel colors into * the span's specular color arrays.  The specular color arrays should no * longer be needed by time this function is called. * Used by blending, logicop and masking functions. * \return pointer to the colors we read. */void *_swrast_get_dest_rgba(GLcontext *ctx, struct gl_renderbuffer *rb,                      SWspan *span){   const GLuint pixelSize = RGBA_PIXEL_SIZE(span->array->ChanType);   void *rbPixels;   /*    * Point rbPixels to a temporary space (use specular color arrays).    */   rbPixels = span->array->attribs[FRAG_ATTRIB_COL1];   /* Get destination values from renderbuffer */   if (span->arrayMask & SPAN_XY) {      _swrast_get_values(ctx, rb, span->end, span->array->x, span->array->y,                         rbPixels, pixelSize);   }   else {      _swrast_get_row(ctx, rb, span->end, span->x, span->y,                      rbPixels, pixelSize);   }   return rbPixels;}

⌨️ 快捷键说明

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