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

📄 s_span.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 4 页
字号:
#endif   /* we have to wait until after occlusion to do this test */   if (ctx->Color.IndexMask == 0) {      /* write no pixels */      span->arrayMask = origArrayMask;      return;   }   /* Interpolate the color indexes if needed */   if (swrast->_FogEnabled ||       ctx->Color.IndexLogicOpEnabled ||       ctx->Color.IndexMask != 0xffffffff ||       (span->arrayMask & SPAN_COVERAGE)) {      if (!(span->arrayMask & SPAN_INDEX) /*span->interpMask & SPAN_INDEX*/) {         interpolate_indexes(ctx, span);      }   }   /* Fog */   if (swrast->_FogEnabled) {      _swrast_fog_ci_span(ctx, span);   }   /* Antialias coverage application */   if (span->arrayMask & SPAN_COVERAGE) {      const GLfloat *coverage = span->array->coverage;      GLuint *index = span->array->index;      GLuint i;      for (i = 0; i < span->end; i++) {         ASSERT(coverage[i] < 16);         index[i] = (index[i] & ~0xf) | ((GLuint) coverage[i]);      }   }   /*    * Write to renderbuffers    */   {      const GLuint numBuffers = fb->_NumColorDrawBuffers;      GLuint buf;      for (buf = 0; buf < numBuffers; buf++) {         struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[buf];         GLuint indexSave[MAX_WIDTH];         ASSERT(rb->_BaseFormat == GL_COLOR_INDEX);         if (numBuffers > 1) {            /* save indexes for second, third renderbuffer writes */            _mesa_memcpy(indexSave, span->array->index,                         span->end * sizeof(indexSave[0]));         }         if (ctx->Color.IndexLogicOpEnabled) {            _swrast_logicop_ci_span(ctx, rb, span);         }         if (ctx->Color.IndexMask != 0xffffffff) {            _swrast_mask_ci_span(ctx, rb, span);         }         if (!(span->arrayMask & SPAN_INDEX) && span->indexStep == 0) {            /* all fragments have same color index */            GLubyte index8;            GLushort index16;            GLuint index32;            void *value;            if (rb->DataType == GL_UNSIGNED_BYTE) {               index8 = FixedToInt(span->index);               value = &index8;            }            else if (rb->DataType == GL_UNSIGNED_SHORT) {               index16 = FixedToInt(span->index);               value = &index16;            }            else {               ASSERT(rb->DataType == GL_UNSIGNED_INT);               index32 = FixedToInt(span->index);               value = &index32;            }            if (span->arrayMask & SPAN_XY) {               rb->PutMonoValues(ctx, rb, span->end, span->array->x,                                  span->array->y, value, span->array->mask);            }            else {               rb->PutMonoRow(ctx, rb, span->end, span->x, span->y,                              value, span->array->mask);            }         }         else {            /* each fragment is a different color */            GLubyte index8[MAX_WIDTH];            GLushort index16[MAX_WIDTH];            void *values;            if (rb->DataType == GL_UNSIGNED_BYTE) {               GLuint k;               for (k = 0; k < span->end; k++) {                  index8[k] = (GLubyte) span->array->index[k];               }               values = index8;            }            else if (rb->DataType == GL_UNSIGNED_SHORT) {               GLuint k;               for (k = 0; k < span->end; k++) {                  index16[k] = (GLushort) span->array->index[k];               }               values = index16;            }            else {               ASSERT(rb->DataType == GL_UNSIGNED_INT);               values = span->array->index;            }            if (span->arrayMask & SPAN_XY) {               rb->PutValues(ctx, rb, span->end,                             span->array->x, span->array->y,                             values, span->array->mask);            }            else {               rb->PutRow(ctx, rb, span->end, span->x, span->y,                          values, span->array->mask);            }         }         if (buf + 1 < numBuffers) {            /* restore original span values */            _mesa_memcpy(span->array->index, indexSave,                         span->end * sizeof(indexSave[0]));         }      } /* for buf */   }   span->interpMask = origInterpMask;   span->arrayMask = origArrayMask;}/** * Add specular colors to primary colors. * Only called during fixed-function operation. * Result is float color array (FRAG_ATTRIB_COL0). */static INLINE voidadd_specular(GLcontext *ctx, SWspan *span){   const SWcontext *swrast = SWRAST_CONTEXT(ctx);   const GLubyte *mask = span->array->mask;   GLfloat (*col0)[4] = span->array->attribs[FRAG_ATTRIB_COL0];   GLfloat (*col1)[4] = span->array->attribs[FRAG_ATTRIB_COL1];   GLuint i;   ASSERT(!ctx->FragmentProgram._Current);   ASSERT(span->arrayMask & SPAN_RGBA);   ASSERT(swrast->_ActiveAttribMask & FRAG_BIT_COL1);   if (span->array->ChanType == GL_FLOAT) {      if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) {         interpolate_active_attribs(ctx, span, FRAG_BIT_COL0);      }   }   else {      /* need float colors */      if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) {         interpolate_float_colors(span);      }   }   if ((span->arrayAttribs & FRAG_BIT_COL1) == 0) {      /* XXX could avoid this and interpolate COL1 in the loop below */      interpolate_active_attribs(ctx, span, FRAG_BIT_COL1);   }   ASSERT(span->arrayAttribs & FRAG_BIT_COL0);   ASSERT(span->arrayAttribs & FRAG_BIT_COL1);   for (i = 0; i < span->end; i++) {      if (mask[i]) {         col0[i][0] += col1[i][0];         col0[i][1] += col1[i][1];         col0[i][2] += col1[i][2];      }   }   span->array->ChanType = GL_FLOAT;}/** * Apply antialiasing coverage value to alpha values. */static INLINE voidapply_aa_coverage(SWspan *span){   const GLfloat *coverage = span->array->coverage;   GLuint i;   if (span->array->ChanType == GL_UNSIGNED_BYTE) {      GLubyte (*rgba)[4] = span->array->rgba8;      for (i = 0; i < span->end; i++) {         const GLfloat a = rgba[i][ACOMP] * coverage[i];         rgba[i][ACOMP] = (GLubyte) CLAMP(a, 0.0, 255.0);         ASSERT(coverage[i] >= 0.0);         ASSERT(coverage[i] <= 1.0);      }   }   else if (span->array->ChanType == GL_UNSIGNED_SHORT) {      GLushort (*rgba)[4] = span->array->rgba16;      for (i = 0; i < span->end; i++) {         const GLfloat a = rgba[i][ACOMP] * coverage[i];         rgba[i][ACOMP] = (GLushort) CLAMP(a, 0.0, 65535.0);      }   }   else {      GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];      for (i = 0; i < span->end; i++) {         rgba[i][ACOMP] = rgba[i][ACOMP] * coverage[i];         /* clamp later */      }   }}/** * Clamp span's float colors to [0,1] */static INLINE voidclamp_colors(SWspan *span){   GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];   GLuint i;   ASSERT(span->array->ChanType == GL_FLOAT);   for (i = 0; i < span->end; i++) {      rgba[i][RCOMP] = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F);      rgba[i][GCOMP] = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F);      rgba[i][BCOMP] = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F);      rgba[i][ACOMP] = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F);   }}/** * Convert the span's color arrays to the given type. * The only way 'output' can be greater than zero is when we have a fragment * program that writes to gl_FragData[1] or higher. * \param output  which fragment program color output is being processed */static INLINE voidconvert_color_type(SWspan *span, GLenum newType, GLuint output){   GLvoid *src, *dst;   if (output > 0 || span->array->ChanType == GL_FLOAT) {      src = span->array->attribs[FRAG_ATTRIB_COL0 + output];      span->array->ChanType = GL_FLOAT;   }   else if (span->array->ChanType == GL_UNSIGNED_BYTE) {      src = span->array->rgba8;   }   else {      ASSERT(span->array->ChanType == GL_UNSIGNED_SHORT);      src = span->array->rgba16;   }   if (newType == GL_UNSIGNED_BYTE) {      dst = span->array->rgba8;   }   else if (newType == GL_UNSIGNED_SHORT) {      dst = span->array->rgba16;   }   else {      dst = span->array->attribs[FRAG_ATTRIB_COL0];   }   _mesa_convert_colors(span->array->ChanType, src,                        newType, dst,                        span->end, span->array->mask);   span->array->ChanType = newType;   span->array->rgba = dst;}/** * Apply fragment shader, fragment program or normal texturing to span. */static INLINE voidshade_texture_span(GLcontext *ctx, SWspan *span){   GLbitfield inputsRead;   /* Determine which fragment attributes are actually needed */   if (ctx->FragmentProgram._Current) {      inputsRead = ctx->FragmentProgram._Current->Base.InputsRead;   }   else {      /* XXX we could be a bit smarter about this */      inputsRead = ~0;   }   if (ctx->FragmentProgram._Current ||       ctx->ATIFragmentShader._Enabled) {      /* programmable shading */      if (span->primitive == GL_BITMAP && span->array->ChanType != GL_FLOAT) {         convert_color_type(span, GL_FLOAT, 0);      }      if (span->primitive != GL_POINT ||	  (span->interpMask & SPAN_RGBA) ||	  ctx->Point.PointSprite) {         /* for single-pixel points, we populated the arrays already */         interpolate_active_attribs(ctx, span, ~0);      }      span->array->ChanType = GL_FLOAT;      if (!(span->arrayMask & SPAN_Z))         _swrast_span_interpolate_z (ctx, span);#if 0      if (inputsRead & FRAG_BIT_WPOS)#else      /* XXX always interpolate wpos so that DDX/DDY work */#endif         interpolate_wpos(ctx, span);      /* Run fragment program/shader now */      if (ctx->FragmentProgram._Current) {         _swrast_exec_fragment_program(ctx, span);      }      else {         ASSERT(ctx->ATIFragmentShader._Enabled);         _swrast_exec_fragment_shader(ctx, span);      }   }   else if (ctx->Texture._EnabledUnits) {      /* conventional texturing */#if CHAN_BITS == 32      if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) {         interpolate_int_colors(ctx, span);      }#else      if (!(span->arrayMask & SPAN_RGBA))         interpolate_int_colors(ctx, span);#endif      if ((span->arrayAttribs & FRAG_BITS_TEX_ANY) == 0x0)         interpolate_texcoords(ctx, span);      _swrast_texture_span(ctx, span);   }}/** * Apply all the per-fragment operations to a span. * This now includes texturing (_swrast_write_texture_span() is history). * This function may modify any of the array values in the span. * span->interpMask and span->arrayMask may be changed but will be restored * to their original values before returning. */void_swrast_write_rgba_span( GLcontext *ctx, SWspan *span){   const SWcontext *swrast = SWRAST_CONTEXT(ctx);   const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);   const GLbitfield origInterpMask = span->interpMask;   const GLbitfield origArrayMask = span->arrayMask;   const GLbitfield origArrayAttribs = span->arrayAttribs;   const GLenum origChanType = span->array->ChanType;   void * const origRgba = span->array->rgba;   const GLboolean shader = (ctx->FragmentProgram._Current                             || ctx->ATIFragmentShader._Enabled);   const GLboolean shaderOrTexture = shader || ctx->Texture._EnabledUnits;   struct gl_framebuffer *fb = ctx->DrawBuffer;   /*   printf("%s()  interp 0x%x  array 0x%x\n", __FUNCTION__,          span->interpMask, span->arrayMask);   */   ASSERT(span->primitive == GL_POINT ||          span->primitive == GL_LINE ||	  span->primitive == GL_POLYGON ||          span->primitive == GL_BITMAP);   ASSERT(span->end <= MAX_WIDTH);   /* Fragment write masks */   if (span->arrayMask & SPAN_MASK) {      /* mask was initialized by caller, probably glBitmap */      span->writeAll = GL_FALSE;   }   else {      _mesa_memset(span->array->mask, 1, span->end);      span->writeAll = GL_TRUE;   }   /* Clip to window/scissor box */   if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) {      if (!clip_span(ctx, span)) {	 return;      }   }#ifdef DEBUG   /* Make sure all fragments are within window bounds */   if (span->arrayMask & SPAN_XY) {      GLuint i;      for (i = 0; i < span->end; i++) {         if (span->array->mask[i]) {            assert(span->array->x[i] >= fb->_Xmin);            assert(span->array->x[i] < fb->_Xmax);            assert(span->array->y[i] >= fb->_Ymin);            assert(span->array->y[i] < fb->_Ymax);         }      }   }#endif   /* Polygon Stippling */   if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) {      stipple_polygon_span(ctx, span);   }   /* This is the normal place to compute the fragment color/Z    * from texturing or shading.    */   if (shaderOrTexture && !swrast->_DeferredTexture) {      shade_texture_span(ctx, span);   }   /* Do the alpha test */   if (ctx->Color.AlphaEnabled) {      if (!_swrast_alpha_test(ctx, span)) {         goto end;      }

⌨️ 快捷键说明

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