Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygens_points.c
Go to the documentation of this file.
00001 /* 00002 * Mesa 3-D graphics library 00003 * Version: 7.1 00004 * 00005 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 00006 * 00007 * Permission is hereby granted, free of charge, to any person obtaining a 00008 * copy of this software and associated documentation files (the "Software"), 00009 * to deal in the Software without restriction, including without limitation 00010 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00011 * and/or sell copies of the Software, and to permit persons to whom the 00012 * Software is furnished to do so, subject to the following conditions: 00013 * 00014 * The above copyright notice and this permission notice shall be included 00015 * in all copies or substantial portions of the Software. 00016 * 00017 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00018 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00019 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00020 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 00021 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 00022 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00023 */ 00024 00025 00026 #include "main/glheader.h" 00027 #include "main/colormac.h" 00028 #include "main/context.h" 00029 #include "main/macros.h" 00030 #include "main/texstate.h" 00031 #include "s_context.h" 00032 #include "s_feedback.h" 00033 #include "s_points.h" 00034 #include "s_span.h" 00035 00036 00040 #define CULL_INVALID(V) \ 00041 do { \ 00042 float tmp = (V)->attrib[FRAG_ATTRIB_WPOS][0] \ 00043 + (V)->attrib[FRAG_ATTRIB_WPOS][1]; \ 00044 if (IS_INF_OR_NAN(tmp)) \ 00045 return; \ 00046 } while(0) 00047 00048 00049 00056 static INLINE GLfloat 00057 get_size(const GLcontext *ctx, const SWvertex *vert, GLboolean smoothed) 00058 { 00059 GLfloat size; 00060 00061 if (ctx->Point._Attenuated || ctx->VertexProgram.PointSizeEnabled) { 00062 /* use vertex's point size */ 00063 size = vert->pointSize; 00064 } 00065 else { 00066 /* use constant point size */ 00067 size = ctx->Point.Size; 00068 } 00069 /* always clamp to user-specified limits */ 00070 size = CLAMP(size, ctx->Point.MinSize, ctx->Point.MaxSize); 00071 /* clamp to implementation limits */ 00072 if (smoothed) 00073 size = CLAMP(size, ctx->Const.MinPointSizeAA, ctx->Const.MaxPointSizeAA); 00074 else 00075 size = CLAMP(size, ctx->Const.MinPointSize, ctx->Const.MaxPointSize); 00076 00077 return size; 00078 } 00079 00080 00084 static void 00085 sprite_point(GLcontext *ctx, const SWvertex *vert) 00086 { 00087 SWcontext *swrast = SWRAST_CONTEXT(ctx); 00088 SWspan span; 00089 GLfloat size; 00090 GLuint tCoords[MAX_TEXTURE_COORD_UNITS + 1]; 00091 GLuint numTcoords = 0; 00092 GLfloat t0, dtdy; 00093 00094 CULL_INVALID(vert); 00095 00096 /* z coord */ 00097 if (ctx->DrawBuffer->Visual.depthBits <= 16) 00098 span.z = FloatToFixed(vert->attrib[FRAG_ATTRIB_WPOS][2] + 0.5F); 00099 else 00100 span.z = (GLuint) (vert->attrib[FRAG_ATTRIB_WPOS][2] + 0.5F); 00101 span.zStep = 0; 00102 00103 size = get_size(ctx, vert, GL_FALSE); 00104 00105 /* span init */ 00106 INIT_SPAN(span, GL_POINT); 00107 span.interpMask = SPAN_Z | SPAN_RGBA; 00108 00109 span.facing = swrast->PointLineFacing; 00110 00111 span.red = ChanToFixed(vert->color[0]); 00112 span.green = ChanToFixed(vert->color[1]); 00113 span.blue = ChanToFixed(vert->color[2]); 00114 span.alpha = ChanToFixed(vert->color[3]); 00115 span.redStep = 0; 00116 span.greenStep = 0; 00117 span.blueStep = 0; 00118 span.alphaStep = 0; 00119 00120 /* need these for fragment programs */ 00121 span.attrStart[FRAG_ATTRIB_WPOS][3] = 1.0F; 00122 span.attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0F; 00123 span.attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0F; 00124 00125 { 00126 GLfloat s, r, dsdx; 00127 00128 /* texcoord / pointcoord interpolants */ 00129 s = 0.0; 00130 dsdx = 1.0 / size; 00131 if (ctx->Point.SpriteOrigin == GL_LOWER_LEFT) { 00132 dtdy = 1.0 / size; 00133 t0 = 0.5 * dtdy; 00134 } 00135 else { 00136 /* GL_UPPER_LEFT */ 00137 dtdy = -1.0 / size; 00138 t0 = 1.0 + 0.5 * dtdy; 00139 } 00140 00141 ATTRIB_LOOP_BEGIN 00142 if (attr >= FRAG_ATTRIB_TEX0 && attr < FRAG_ATTRIB_VAR0) { 00143 const GLuint u = attr - FRAG_ATTRIB_TEX0; 00144 /* a texcoord */ 00145 if (ctx->Point.CoordReplace[u]) { 00146 tCoords[numTcoords++] = attr; 00147 00148 if (ctx->Point.SpriteRMode == GL_ZERO) 00149 r = 0.0F; 00150 else if (ctx->Point.SpriteRMode == GL_S) 00151 r = vert->attrib[attr][0]; 00152 else /* GL_R */ 00153 r = vert->attrib[attr][2]; 00154 00155 span.attrStart[attr][0] = s; 00156 span.attrStart[attr][1] = 0.0; /* overwritten below */ 00157 span.attrStart[attr][2] = r; 00158 span.attrStart[attr][3] = 1.0; 00159 00160 span.attrStepX[attr][0] = dsdx; 00161 span.attrStepX[attr][1] = 0.0; 00162 span.attrStepX[attr][2] = 0.0; 00163 span.attrStepX[attr][3] = 0.0; 00164 00165 span.attrStepY[attr][0] = 0.0; 00166 span.attrStepY[attr][1] = dtdy; 00167 span.attrStepY[attr][2] = 0.0; 00168 span.attrStepY[attr][3] = 0.0; 00169 00170 continue; 00171 } 00172 } 00173 else if (attr == FRAG_ATTRIB_FOGC) { 00174 /* GLSL gl_PointCoord is stored in fog.zw */ 00175 span.attrStart[FRAG_ATTRIB_FOGC][2] = 0.0; 00176 span.attrStart[FRAG_ATTRIB_FOGC][3] = 0.0; /* t0 set below */ 00177 span.attrStepX[FRAG_ATTRIB_FOGC][2] = dsdx; 00178 span.attrStepX[FRAG_ATTRIB_FOGC][3] = 0.0; 00179 span.attrStepY[FRAG_ATTRIB_FOGC][2] = 0.0; 00180 span.attrStepY[FRAG_ATTRIB_FOGC][3] = dtdy; 00181 tCoords[numTcoords++] = FRAG_ATTRIB_FOGC; 00182 continue; 00183 } 00184 /* use vertex's texcoord/attrib */ 00185 COPY_4V(span.attrStart[attr], vert->attrib[attr]); 00186 ASSIGN_4V(span.attrStepX[attr], 0, 0, 0, 0); 00187 ASSIGN_4V(span.attrStepY[attr], 0, 0, 0, 0); 00188 ATTRIB_LOOP_END; 00189 } 00190 00191 /* compute pos, bounds and render */ 00192 { 00193 const GLfloat x = vert->attrib[FRAG_ATTRIB_WPOS][0]; 00194 const GLfloat y = vert->attrib[FRAG_ATTRIB_WPOS][1]; 00195 GLint iSize = (GLint) (size + 0.5F); 00196 GLint xmin, xmax, ymin, ymax, iy; 00197 GLint iRadius; 00198 GLfloat tcoord = t0; 00199 00200 iSize = MAX2(1, iSize); 00201 iRadius = iSize / 2; 00202 00203 if (iSize & 1) { 00204 /* odd size */ 00205 xmin = (GLint) (x - iRadius); 00206 xmax = (GLint) (x + iRadius); 00207 ymin = (GLint) (y - iRadius); 00208 ymax = (GLint) (y + iRadius); 00209 } 00210 else { 00211 /* even size */ 00212 /* 0.501 factor allows conformance to pass */ 00213 xmin = (GLint) (x + 0.501) - iRadius; 00214 xmax = xmin + iSize - 1; 00215 ymin = (GLint) (y + 0.501) - iRadius; 00216 ymax = ymin + iSize - 1; 00217 } 00218 00219 /* render spans */ 00220 for (iy = ymin; iy <= ymax; iy++) { 00221 GLuint i; 00222 /* setup texcoord T for this row */ 00223 for (i = 0; i < numTcoords; i++) { 00224 if (tCoords[i] == FRAG_ATTRIB_FOGC) 00225 span.attrStart[FRAG_ATTRIB_FOGC][3] = tcoord; 00226 else 00227 span.attrStart[tCoords[i]][1] = tcoord; 00228 } 00229 00230 /* these might get changed by span clipping */ 00231 span.x = xmin; 00232 span.y = iy; 00233 span.end = xmax - xmin + 1; 00234 00235 _swrast_write_rgba_span(ctx, &span); 00236 00237 tcoord += dtdy; 00238 } 00239 } 00240 } 00241 00242 00246 static void 00247 smooth_point(GLcontext *ctx, const SWvertex *vert) 00248 { 00249 SWcontext *swrast = SWRAST_CONTEXT(ctx); 00250 const GLboolean ciMode = !ctx->Visual.rgbMode; 00251 SWspan span; 00252 GLfloat size, alphaAtten; 00253 00254 CULL_INVALID(vert); 00255 00256 /* z coord */ 00257 if (ctx->DrawBuffer->Visual.depthBits <= 16) 00258 span.z = FloatToFixed(vert->attrib[FRAG_ATTRIB_WPOS][2] + 0.5F); 00259 else 00260 span.z = (GLuint) (vert->attrib[FRAG_ATTRIB_WPOS][2] + 0.5F); 00261 span.zStep = 0; 00262 00263 size = get_size(ctx, vert, GL_TRUE); 00264 00265 /* alpha attenuation / fade factor */ 00266 if (ctx->Multisample._Enabled) { 00267 if (vert->pointSize >= ctx->Point.Threshold) { 00268 alphaAtten = 1.0F; 00269 } 00270 else { 00271 GLfloat dsize = vert->pointSize / ctx->Point.Threshold; 00272 alphaAtten = dsize * dsize; 00273 } 00274 } 00275 else { 00276 alphaAtten = 1.0; 00277 } 00278 (void) alphaAtten; /* not used */ 00279 00280 /* span init */ 00281 INIT_SPAN(span, GL_POINT); 00282 span.interpMask = SPAN_Z | SPAN_RGBA; 00283 span.arrayMask = SPAN_COVERAGE | SPAN_MASK; 00284 00285 span.facing = swrast->PointLineFacing; 00286 00287 span.red = ChanToFixed(vert->color[0]); 00288 span.green = ChanToFixed(vert->color[1]); 00289 span.blue = ChanToFixed(vert->color[2]); 00290 span.alpha = ChanToFixed(vert->color[3]); 00291 span.redStep = 0; 00292 span.greenStep = 0; 00293 span.blueStep = 0; 00294 span.alphaStep = 0; 00295 00296 /* need these for fragment programs */ 00297 span.attrStart[FRAG_ATTRIB_WPOS][3] = 1.0F; 00298 span.attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0F; 00299 span.attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0F; 00300 00301 ATTRIB_LOOP_BEGIN 00302 COPY_4V(span.attrStart[attr], vert->attrib[attr]); 00303 ASSIGN_4V(span.attrStepX[attr], 0, 0, 0, 0); 00304 ASSIGN_4V(span.attrStepY[attr], 0, 0, 0, 0); 00305 ATTRIB_LOOP_END 00306 00307 /* compute pos, bounds and render */ 00308 { 00309 const GLfloat x = vert->attrib[FRAG_ATTRIB_WPOS][0]; 00310 const GLfloat y = vert->attrib[FRAG_ATTRIB_WPOS][1]; 00311 const GLfloat radius = 0.5F * size; 00312 const GLfloat rmin = radius - 0.7071F; /* 0.7071 = sqrt(2)/2 */ 00313 const GLfloat rmax = radius + 0.7071F; 00314 const GLfloat rmin2 = MAX2(0.0F, rmin * rmin); 00315 const GLfloat rmax2 = rmax * rmax; 00316 const GLfloat cscale = 1.0F / (rmax2 - rmin2); 00317 const GLint xmin = (GLint) (x - radius); 00318 const GLint xmax = (GLint) (x + radius); 00319 const GLint ymin = (GLint) (y - radius); 00320 const GLint ymax = (GLint) (y + radius); 00321 GLint ix, iy; 00322 00323 for (iy = ymin; iy <= ymax; iy++) { 00324 00325 /* these might get changed by span clipping */ 00326 span.x = xmin; 00327 span.y = iy; 00328 span.end = xmax - xmin + 1; 00329 00330 /* compute coverage for each pixel in span */ 00331 for (ix = xmin; ix <= xmax; ix++) { 00332 const GLfloat dx = ix - x + 0.5F; 00333 const GLfloat dy = iy - y + 0.5F; 00334 const GLfloat dist2 = dx * dx + dy * dy; 00335 GLfloat coverage; 00336 00337 if (dist2 < rmax2) { 00338 if (dist2 >= rmin2) { 00339 /* compute partial coverage */ 00340 coverage = 1.0F - (dist2 - rmin2) * cscale; 00341 if (ciMode) { 00342 /* coverage in [0,15] */ 00343 coverage *= 15.0; 00344 } 00345 } 00346 else { 00347 /* full coverage */ 00348 coverage = 1.0F; 00349 } 00350 span.array->mask[ix - xmin] = 1; 00351 } 00352 else { 00353 /* zero coverage - fragment outside the radius */ 00354 coverage = 0.0; 00355 span.array->mask[ix - xmin] = 0; 00356 } 00357 span.array->coverage[ix - xmin] = coverage; 00358 } 00359 00360 /* render span */ 00361 _swrast_write_rgba_span(ctx, &span); 00362 00363 } 00364 } 00365 } 00366 00367 00371 static void 00372 large_point(GLcontext *ctx, const SWvertex *vert) 00373 { 00374 SWcontext *swrast = SWRAST_CONTEXT(ctx); 00375 const GLboolean ciMode = !ctx->Visual.rgbMode; 00376 SWspan span; 00377 GLfloat size; 00378 00379 CULL_INVALID(vert); 00380 00381 /* z coord */ 00382 if (ctx->DrawBuffer->Visual.depthBits <= 16) 00383 span.z = FloatToFixed(vert->attrib[FRAG_ATTRIB_WPOS][2] + 0.5F); 00384 else 00385 span.z = (GLuint) (vert->attrib[FRAG_ATTRIB_WPOS][2] + 0.5F); 00386 span.zStep = 0; 00387 00388 size = get_size(ctx, vert, GL_FALSE); 00389 00390 /* span init */ 00391 INIT_SPAN(span, GL_POINT); 00392 span.arrayMask = SPAN_XY; 00393 span.facing = swrast->PointLineFacing; 00394 00395 if (ciMode) { 00396 span.interpMask = SPAN_Z | SPAN_INDEX; 00397 span.index = FloatToFixed(vert->attrib[FRAG_ATTRIB_CI][0]); 00398 span.indexStep = 0; 00399 } 00400 else { 00401 span.interpMask = SPAN_Z | SPAN_RGBA; 00402 span.red = ChanToFixed(vert->color[0]); 00403 span.green = ChanToFixed(vert->color[1]); 00404 span.blue = ChanToFixed(vert->color[2]); 00405 span.alpha = ChanToFixed(vert->color[3]); 00406 span.redStep = 0; 00407 span.greenStep = 0; 00408 span.blueStep = 0; 00409 span.alphaStep = 0; 00410 } 00411 00412 /* need these for fragment programs */ 00413 span.attrStart[FRAG_ATTRIB_WPOS][3] = 1.0F; 00414 span.attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0F; 00415 span.attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0F; 00416 00417 ATTRIB_LOOP_BEGIN 00418 COPY_4V(span.attrStart[attr], vert->attrib[attr]); 00419 ASSIGN_4V(span.attrStepX[attr], 0, 0, 0, 0); 00420 ASSIGN_4V(span.attrStepY[attr], 0, 0, 0, 0); 00421 ATTRIB_LOOP_END 00422 00423 /* compute pos, bounds and render */ 00424 { 00425 const GLfloat x = vert->attrib[FRAG_ATTRIB_WPOS][0]; 00426 const GLfloat y = vert->attrib[FRAG_ATTRIB_WPOS][1]; 00427 GLint iSize = (GLint) (size + 0.5F); 00428 GLint xmin, xmax, ymin, ymax, ix, iy; 00429 GLint iRadius; 00430 00431 iSize = MAX2(1, iSize); 00432 iRadius = iSize / 2; 00433 00434 if (iSize & 1) { 00435 /* odd size */ 00436 xmin = (GLint) (x - iRadius); 00437 xmax = (GLint) (x + iRadius); 00438 ymin = (GLint) (y - iRadius); 00439 ymax = (GLint) (y + iRadius); 00440 } 00441 else { 00442 /* even size */ 00443 /* 0.501 factor allows conformance to pass */ 00444 xmin = (GLint) (x + 0.501) - iRadius; 00445 xmax = xmin + iSize - 1; 00446 ymin = (GLint) (y + 0.501) - iRadius; 00447 ymax = ymin + iSize - 1; 00448 } 00449 00450 /* generate fragments */ 00451 span.end = 0; 00452 for (iy = ymin; iy <= ymax; iy++) { 00453 for (ix = xmin; ix <= xmax; ix++) { 00454 span.array->x[span.end] = ix; 00455 span.array->y[span.end] = iy; 00456 span.end++; 00457 } 00458 } 00459 assert(span.end <= MAX_WIDTH); 00460 _swrast_write_rgba_span(ctx, &span); 00461 } 00462 } 00463 00464 00468 static void 00469 pixel_point(GLcontext *ctx, const SWvertex *vert) 00470 { 00471 SWcontext *swrast = SWRAST_CONTEXT(ctx); 00472 const GLboolean ciMode = !ctx->Visual.rgbMode; 00473 /* 00474 * Note that unlike the other functions, we put single-pixel points 00475 * into a special span array in order to render as many points as 00476 * possible with a single _swrast_write_rgba_span() call. 00477 */ 00478 SWspan *span = &(swrast->PointSpan); 00479 GLuint count; 00480 00481 CULL_INVALID(vert); 00482 00483 /* Span init */ 00484 span->interpMask = 0; 00485 span->arrayMask = SPAN_XY | SPAN_Z; 00486 if (ciMode) 00487 span->arrayMask |= SPAN_INDEX; 00488 else 00489 span->arrayMask |= SPAN_RGBA; 00490 /*span->arrayMask |= SPAN_LAMBDA;*/ 00491 span->arrayAttribs = swrast->_ActiveAttribMask; /* we'll produce these vals */ 00492 00493 /* need these for fragment programs */ 00494 span->attrStart[FRAG_ATTRIB_WPOS][3] = 1.0F; 00495 span->attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0F; 00496 span->attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0F; 00497 00498 /* check if we need to flush */ 00499 if (span->end >= MAX_WIDTH || 00500 (swrast->_RasterMask & (BLEND_BIT | LOGIC_OP_BIT | MASKING_BIT)) || 00501 span->facing != swrast->PointLineFacing) { 00502 if (span->end > 0) { 00503 if (ciMode) 00504 _swrast_write_index_span(ctx, span); 00505 else 00506 _swrast_write_rgba_span(ctx, span); 00507 span->end = 0; 00508 } 00509 } 00510 00511 count = span->end; 00512 00513 span->facing = swrast->PointLineFacing; 00514 00515 /* fragment attributes */ 00516 if (ciMode) { 00517 span->array->index[count] = (GLuint) vert->attrib[FRAG_ATTRIB_CI][0]; 00518 } 00519 else { 00520 span->array->rgba[count][RCOMP] = vert->color[0]; 00521 span->array->rgba[count][GCOMP] = vert->color[1]; 00522 span->array->rgba[count][BCOMP] = vert->color[2]; 00523 span->array->rgba[count][ACOMP] = vert->color[3]; 00524 } 00525 ATTRIB_LOOP_BEGIN 00526 COPY_4V(span->array->attribs[attr][count], vert->attrib[attr]); 00527 ATTRIB_LOOP_END 00528 00529 /* fragment position */ 00530 span->array->x[count] = (GLint) vert->attrib[FRAG_ATTRIB_WPOS][0]; 00531 span->array->y[count] = (GLint) vert->attrib[FRAG_ATTRIB_WPOS][1]; 00532 span->array->z[count] = (GLint) (vert->attrib[FRAG_ATTRIB_WPOS][2] + 0.5F); 00533 00534 span->end = count + 1; 00535 ASSERT(span->end <= MAX_WIDTH); 00536 } 00537 00538 00543 void 00544 _swrast_add_spec_terms_point(GLcontext *ctx, const SWvertex *v0) 00545 { 00546 SWvertex *ncv0 = (SWvertex *) v0; /* cast away const */ 00547 GLfloat rSum, gSum, bSum; 00548 GLchan cSave[4]; 00549 00550 /* save */ 00551 COPY_CHAN4(cSave, ncv0->color); 00552 /* sum */ 00553 rSum = CHAN_TO_FLOAT(ncv0->color[0]) + ncv0->attrib[FRAG_ATTRIB_COL1][0]; 00554 gSum = CHAN_TO_FLOAT(ncv0->color[1]) + ncv0->attrib[FRAG_ATTRIB_COL1][1]; 00555 bSum = CHAN_TO_FLOAT(ncv0->color[2]) + ncv0->attrib[FRAG_ATTRIB_COL1][2]; 00556 UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[0], rSum); 00557 UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[1], gSum); 00558 UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[2], bSum); 00559 /* draw */ 00560 SWRAST_CONTEXT(ctx)->SpecPoint(ctx, ncv0); 00561 /* restore */ 00562 COPY_CHAN4(ncv0->color, cSave); 00563 } 00564 00565 00569 void 00570 _swrast_choose_point(GLcontext *ctx) 00571 { 00572 SWcontext *swrast = SWRAST_CONTEXT(ctx); 00573 00574 if (ctx->RenderMode == GL_RENDER) { 00575 if (ctx->Point.PointSprite) { 00576 swrast->Point = sprite_point; 00577 } 00578 else if (ctx->Point.SmoothFlag) { 00579 swrast->Point = smooth_point; 00580 } 00581 else if (ctx->Point.Size > 1.0 || 00582 ctx->Point._Attenuated || 00583 ctx->VertexProgram.PointSizeEnabled) { 00584 swrast->Point = large_point; 00585 } 00586 else { 00587 swrast->Point = pixel_point; 00588 } 00589 } 00590 else if (ctx->RenderMode == GL_FEEDBACK) { 00591 swrast->Point = _swrast_feedback_point; 00592 } 00593 else { 00594 /* GL_SELECT mode */ 00595 swrast->Point = _swrast_select_point; 00596 } 00597 } Generated on Sat May 26 2012 04:19:33 for ReactOS by
1.7.6.1
|