1e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/* 2e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Mesa 3-D graphics library 31d52b6aaf41b32aaf8d1cdf5a3cd5ff4ecba28f4Brian * Version: 7.1 422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * 51d52b6aaf41b32aaf8d1cdf5a3cd5ff4ecba28f4Brian * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * 7e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a 8e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * copy of this software and associated documentation files (the "Software"), 9e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * to deal in the Software without restriction, including without limitation 10e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * and/or sell copies of the Software, and to permit persons to whom the 12e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Software is furnished to do so, subject to the following conditions: 1322144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * 14e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * The above copyright notice and this permission notice shall be included 15e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * in all copies or substantial portions of the Software. 1622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * 17e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 24e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 25e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 26bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/glheader.h" 27bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/colormac.h" 28bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/macros.h" 29cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#include "s_context.h" 30cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#include "s_feedback.h" 31cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#include "s_points.h" 32e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_span.h" 33e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 34e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 35fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian/** 36fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian * Used to cull points with invalid coords 37e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 38fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian#define CULL_INVALID(V) \ 39fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian do { \ 40fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian float tmp = (V)->attrib[FRAG_ATTRIB_WPOS][0] \ 41fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian + (V)->attrib[FRAG_ATTRIB_WPOS][1]; \ 42fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian if (IS_INF_OR_NAN(tmp)) \ 43fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian return; \ 44fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian } while(0) 45e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 46e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 470fd679a1903d997b53fe20b86821a58c1a66262fBrian 480fd679a1903d997b53fe20b86821a58c1a66262fBrian/** 490fd679a1903d997b53fe20b86821a58c1a66262fBrian * Get/compute the point size. 500fd679a1903d997b53fe20b86821a58c1a66262fBrian * The size may come from a vertex shader, or computed with attentuation 510fd679a1903d997b53fe20b86821a58c1a66262fBrian * or just the glPointSize value. 520fd679a1903d997b53fe20b86821a58c1a66262fBrian * Must also clamp to user-defined range and implmentation limits. 530fd679a1903d997b53fe20b86821a58c1a66262fBrian */ 549520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLfloat 55f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergget_size(const struct gl_context *ctx, const SWvertex *vert, GLboolean smoothed) 560fd679a1903d997b53fe20b86821a58c1a66262fBrian{ 570fd679a1903d997b53fe20b86821a58c1a66262fBrian GLfloat size; 580fd679a1903d997b53fe20b86821a58c1a66262fBrian 590fd679a1903d997b53fe20b86821a58c1a66262fBrian if (ctx->Point._Attenuated || ctx->VertexProgram.PointSizeEnabled) { 600fd679a1903d997b53fe20b86821a58c1a66262fBrian /* use vertex's point size */ 610fd679a1903d997b53fe20b86821a58c1a66262fBrian size = vert->pointSize; 620fd679a1903d997b53fe20b86821a58c1a66262fBrian } 630fd679a1903d997b53fe20b86821a58c1a66262fBrian else { 640fd679a1903d997b53fe20b86821a58c1a66262fBrian /* use constant point size */ 650fd679a1903d997b53fe20b86821a58c1a66262fBrian size = ctx->Point.Size; 660fd679a1903d997b53fe20b86821a58c1a66262fBrian } 670fd679a1903d997b53fe20b86821a58c1a66262fBrian /* always clamp to user-specified limits */ 680fd679a1903d997b53fe20b86821a58c1a66262fBrian size = CLAMP(size, ctx->Point.MinSize, ctx->Point.MaxSize); 690fd679a1903d997b53fe20b86821a58c1a66262fBrian /* clamp to implementation limits */ 700fd679a1903d997b53fe20b86821a58c1a66262fBrian if (smoothed) 710fd679a1903d997b53fe20b86821a58c1a66262fBrian size = CLAMP(size, ctx->Const.MinPointSizeAA, ctx->Const.MaxPointSizeAA); 720fd679a1903d997b53fe20b86821a58c1a66262fBrian else 730fd679a1903d997b53fe20b86821a58c1a66262fBrian size = CLAMP(size, ctx->Const.MinPointSize, ctx->Const.MaxPointSize); 740fd679a1903d997b53fe20b86821a58c1a66262fBrian 750fd679a1903d997b53fe20b86821a58c1a66262fBrian return size; 760fd679a1903d997b53fe20b86821a58c1a66262fBrian} 770fd679a1903d997b53fe20b86821a58c1a66262fBrian 780fd679a1903d997b53fe20b86821a58c1a66262fBrian 79fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian/** 80fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian * Draw a point sprite 81e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 82fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brianstatic void 83f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsprite_point(struct gl_context *ctx, const SWvertex *vert) 84fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian{ 85fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian SWcontext *swrast = SWRAST_CONTEXT(ctx); 86fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian SWspan span; 87fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian GLfloat size; 88e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian GLuint tCoords[MAX_TEXTURE_COORD_UNITS + 1]; 89fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian GLuint numTcoords = 0; 90fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian GLfloat t0, dtdy; 91fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 92fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian CULL_INVALID(vert); 93fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 94fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /* z coord */ 95fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian if (ctx->DrawBuffer->Visual.depthBits <= 16) 96fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.z = FloatToFixed(vert->attrib[FRAG_ATTRIB_WPOS][2] + 0.5F); 97fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian else 98fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.z = (GLuint) (vert->attrib[FRAG_ATTRIB_WPOS][2] + 0.5F); 99fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.zStep = 0; 100fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 1010fd679a1903d997b53fe20b86821a58c1a66262fBrian size = get_size(ctx, vert, GL_FALSE); 102fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 103fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /* span init */ 104f4b103dc993491355ec3e3640d9cb060138175c2Brian INIT_SPAN(span, GL_POINT); 105fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.interpMask = SPAN_Z | SPAN_RGBA; 106fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 107fcd7c37fd3d0f61cf6ac81170bc0b3fca64ad9bbBrian span.facing = swrast->PointLineFacing; 108fcd7c37fd3d0f61cf6ac81170bc0b3fca64ad9bbBrian 109fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.red = ChanToFixed(vert->color[0]); 110fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.green = ChanToFixed(vert->color[1]); 111fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.blue = ChanToFixed(vert->color[2]); 112fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.alpha = ChanToFixed(vert->color[3]); 113fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.redStep = 0; 114fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.greenStep = 0; 115fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.blueStep = 0; 116fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.alphaStep = 0; 117fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 118fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /* need these for fragment programs */ 119fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.attrStart[FRAG_ATTRIB_WPOS][3] = 1.0F; 120fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0F; 121fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0F; 122fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 123e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian { 124e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian GLfloat s, r, dsdx; 125e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian 126e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian /* texcoord / pointcoord interpolants */ 127880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul s = 0.0F; 128880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul dsdx = 1.0F / size; 129e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian if (ctx->Point.SpriteOrigin == GL_LOWER_LEFT) { 130880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul dtdy = 1.0F / size; 131880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul t0 = 0.5F * dtdy; 132e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian } 133e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian else { 134e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian /* GL_UPPER_LEFT */ 135880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul dtdy = -1.0F / size; 136880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul t0 = 1.0F + 0.5F * dtdy; 137e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian } 138fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 139e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian ATTRIB_LOOP_BEGIN 140f7618f4f37d42461b1a6feaa392935d1ae703873Brian Paul if (attr >= FRAG_ATTRIB_TEX0 && attr <= FRAG_ATTRIB_TEX7) { 141f7618f4f37d42461b1a6feaa392935d1ae703873Brian Paul /* a texcoord attribute */ 142e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian const GLuint u = attr - FRAG_ATTRIB_TEX0; 143f7618f4f37d42461b1a6feaa392935d1ae703873Brian Paul ASSERT(u < Elements(ctx->Point.CoordReplace)); 144e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian if (ctx->Point.CoordReplace[u]) { 145e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian tCoords[numTcoords++] = attr; 146e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian 147e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian if (ctx->Point.SpriteRMode == GL_ZERO) 148e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian r = 0.0F; 149e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian else if (ctx->Point.SpriteRMode == GL_S) 150e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian r = vert->attrib[attr][0]; 151e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian else /* GL_R */ 152e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian r = vert->attrib[attr][2]; 153e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian 154e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian span.attrStart[attr][0] = s; 155e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian span.attrStart[attr][1] = 0.0; /* overwritten below */ 156e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian span.attrStart[attr][2] = r; 157e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian span.attrStart[attr][3] = 1.0; 158e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian 159e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian span.attrStepX[attr][0] = dsdx; 160e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian span.attrStepX[attr][1] = 0.0; 161e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian span.attrStepX[attr][2] = 0.0; 162e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian span.attrStepX[attr][3] = 0.0; 163e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian 164e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian span.attrStepY[attr][0] = 0.0; 165e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian span.attrStepY[attr][1] = dtdy; 166e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian span.attrStepY[attr][2] = 0.0; 167e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian span.attrStepY[attr][3] = 0.0; 168e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian 169e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian continue; 170fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian } 171e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian } 1729d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul else if (attr == FRAG_ATTRIB_PNTC) { 1739d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul /* GLSL gl_PointCoord.xy (.zw undefined) */ 1749d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul span.attrStart[FRAG_ATTRIB_PNTC][0] = 0.0; 1759d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul span.attrStart[FRAG_ATTRIB_PNTC][1] = 0.0; /* t0 set below */ 1769d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul span.attrStepX[FRAG_ATTRIB_PNTC][0] = dsdx; 1779d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul span.attrStepX[FRAG_ATTRIB_PNTC][1] = 0.0; 1789d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul span.attrStepY[FRAG_ATTRIB_PNTC][0] = 0.0; 1799d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul span.attrStepY[FRAG_ATTRIB_PNTC][1] = dtdy; 1809d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul tCoords[numTcoords++] = FRAG_ATTRIB_PNTC; 181fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian continue; 182fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian } 183e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian /* use vertex's texcoord/attrib */ 184e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian COPY_4V(span.attrStart[attr], vert->attrib[attr]); 185e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian ASSIGN_4V(span.attrStepX[attr], 0, 0, 0, 0); 186e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian ASSIGN_4V(span.attrStepY[attr], 0, 0, 0, 0); 187e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian ATTRIB_LOOP_END; 188e48f0b09abe42aa3393a492af07e53b76ad0ff3cBrian } 189fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 190fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /* compute pos, bounds and render */ 191fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian { 192fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian const GLfloat x = vert->attrib[FRAG_ATTRIB_WPOS][0]; 193fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian const GLfloat y = vert->attrib[FRAG_ATTRIB_WPOS][1]; 194fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian GLint iSize = (GLint) (size + 0.5F); 195fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian GLint xmin, xmax, ymin, ymax, iy; 196fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian GLint iRadius; 197fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian GLfloat tcoord = t0; 198fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 199fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian iSize = MAX2(1, iSize); 200fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian iRadius = iSize / 2; 201fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 202fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian if (iSize & 1) { 203fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /* odd size */ 204fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian xmin = (GLint) (x - iRadius); 205fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian xmax = (GLint) (x + iRadius); 206fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian ymin = (GLint) (y - iRadius); 207fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian ymax = (GLint) (y + iRadius); 208fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian } 209fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian else { 210fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /* even size */ 2114f9d29cd4e876cd202a7d3e81f6d91fc7f9625a2Brian /* 0.501 factor allows conformance to pass */ 2124f9d29cd4e876cd202a7d3e81f6d91fc7f9625a2Brian xmin = (GLint) (x + 0.501) - iRadius; 213fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian xmax = xmin + iSize - 1; 2144f9d29cd4e876cd202a7d3e81f6d91fc7f9625a2Brian ymin = (GLint) (y + 0.501) - iRadius; 215fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian ymax = ymin + iSize - 1; 216fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian } 217e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 218fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /* render spans */ 219fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian for (iy = ymin; iy <= ymax; iy++) { 220fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian GLuint i; 221fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /* setup texcoord T for this row */ 222fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian for (i = 0; i < numTcoords; i++) { 2239d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul span.attrStart[tCoords[i]][1] = tcoord; 224fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian } 225e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 226fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /* these might get changed by span clipping */ 227fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.x = xmin; 228fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.y = iy; 229fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.end = xmax - xmin + 1; 230e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 231fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian _swrast_write_rgba_span(ctx, &span); 232e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 233fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian tcoord += dtdy; 234fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian } 235fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian } 236fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian} 237e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 238cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell 239fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian/** 240fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian * Draw smooth/antialiased point. RGB or CI mode. 241e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 242fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brianstatic void 243f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsmooth_point(struct gl_context *ctx, const SWvertex *vert) 244fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian{ 245fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian SWcontext *swrast = SWRAST_CONTEXT(ctx); 246fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian SWspan span; 247fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian GLfloat size, alphaAtten; 248fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 249fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian CULL_INVALID(vert); 250fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 251fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /* z coord */ 252fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian if (ctx->DrawBuffer->Visual.depthBits <= 16) 253fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.z = FloatToFixed(vert->attrib[FRAG_ATTRIB_WPOS][2] + 0.5F); 254fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian else 255fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.z = (GLuint) (vert->attrib[FRAG_ATTRIB_WPOS][2] + 0.5F); 256fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.zStep = 0; 257fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 2580fd679a1903d997b53fe20b86821a58c1a66262fBrian size = get_size(ctx, vert, GL_TRUE); 259e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 260fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /* alpha attenuation / fade factor */ 2615ef4e4ffb8053db87f52df3c9b2ddb71d9c7d6e5Roland Scheidegger if (ctx->Multisample._Enabled) { 262fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian if (vert->pointSize >= ctx->Point.Threshold) { 263fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian alphaAtten = 1.0F; 264fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian } 265fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian else { 266fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian GLfloat dsize = vert->pointSize / ctx->Point.Threshold; 267fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian alphaAtten = dsize * dsize; 268fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian } 269fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian } 270fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian else { 271fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian alphaAtten = 1.0; 272fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian } 273fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian (void) alphaAtten; /* not used */ 274fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 275fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /* span init */ 276f4b103dc993491355ec3e3640d9cb060138175c2Brian INIT_SPAN(span, GL_POINT); 277fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.interpMask = SPAN_Z | SPAN_RGBA; 278fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.arrayMask = SPAN_COVERAGE | SPAN_MASK; 279fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 280fcd7c37fd3d0f61cf6ac81170bc0b3fca64ad9bbBrian span.facing = swrast->PointLineFacing; 281fcd7c37fd3d0f61cf6ac81170bc0b3fca64ad9bbBrian 282fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.red = ChanToFixed(vert->color[0]); 283fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.green = ChanToFixed(vert->color[1]); 284fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.blue = ChanToFixed(vert->color[2]); 285fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.alpha = ChanToFixed(vert->color[3]); 286fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.redStep = 0; 287fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.greenStep = 0; 288fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.blueStep = 0; 289fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.alphaStep = 0; 290fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 291fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /* need these for fragment programs */ 292fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.attrStart[FRAG_ATTRIB_WPOS][3] = 1.0F; 293fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0F; 294fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0F; 295fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 296fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian ATTRIB_LOOP_BEGIN 297fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian COPY_4V(span.attrStart[attr], vert->attrib[attr]); 298fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian ASSIGN_4V(span.attrStepX[attr], 0, 0, 0, 0); 299fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian ASSIGN_4V(span.attrStepY[attr], 0, 0, 0, 0); 300fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian ATTRIB_LOOP_END 301fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 302fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /* compute pos, bounds and render */ 303fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian { 304fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian const GLfloat x = vert->attrib[FRAG_ATTRIB_WPOS][0]; 305fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian const GLfloat y = vert->attrib[FRAG_ATTRIB_WPOS][1]; 306fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian const GLfloat radius = 0.5F * size; 307fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian const GLfloat rmin = radius - 0.7071F; /* 0.7071 = sqrt(2)/2 */ 308fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian const GLfloat rmax = radius + 0.7071F; 309fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian const GLfloat rmin2 = MAX2(0.0F, rmin * rmin); 310fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian const GLfloat rmax2 = rmax * rmax; 311fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian const GLfloat cscale = 1.0F / (rmax2 - rmin2); 312fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian const GLint xmin = (GLint) (x - radius); 313fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian const GLint xmax = (GLint) (x + radius); 314fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian const GLint ymin = (GLint) (y - radius); 315fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian const GLint ymax = (GLint) (y + radius); 316fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian GLint ix, iy; 317fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 318fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian for (iy = ymin; iy <= ymax; iy++) { 319fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 320fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /* these might get changed by span clipping */ 321fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.x = xmin; 322fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.y = iy; 323fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.end = xmax - xmin + 1; 324fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 325fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /* compute coverage for each pixel in span */ 326fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian for (ix = xmin; ix <= xmax; ix++) { 327fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian const GLfloat dx = ix - x + 0.5F; 328fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian const GLfloat dy = iy - y + 0.5F; 329fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian const GLfloat dist2 = dx * dx + dy * dy; 330fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian GLfloat coverage; 331fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 332fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian if (dist2 < rmax2) { 333fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian if (dist2 >= rmin2) { 334fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /* compute partial coverage */ 335fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian coverage = 1.0F - (dist2 - rmin2) * cscale; 336fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian } 337fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian else { 338fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /* full coverage */ 339fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian coverage = 1.0F; 340fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian } 341fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.array->mask[ix - xmin] = 1; 342fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian } 343fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian else { 344fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /* zero coverage - fragment outside the radius */ 345fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian coverage = 0.0; 346fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.array->mask[ix - xmin] = 0; 347fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian } 348fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.array->coverage[ix - xmin] = coverage; 349fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian } 350e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 351fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /* render span */ 352fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian _swrast_write_rgba_span(ctx, &span); 353e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 354fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian } 355fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian } 356fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian} 3572fd9c8690fa86b17c42afcc73307d2232b8f79f6Brian Paul 3582fd9c8690fa86b17c42afcc73307d2232b8f79f6Brian Paul 359fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian/** 360fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian * Draw large (size >= 1) non-AA point. RGB or CI mode. 3612fd9c8690fa86b17c42afcc73307d2232b8f79f6Brian Paul */ 362fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brianstatic void 363f9995b30756140724f41daf963fa06167912be7fKristian Høgsberglarge_point(struct gl_context *ctx, const SWvertex *vert) 364fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian{ 365fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian SWcontext *swrast = SWRAST_CONTEXT(ctx); 366fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian SWspan span; 367fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian GLfloat size; 368fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 369fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian CULL_INVALID(vert); 370fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 371fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /* z coord */ 372fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian if (ctx->DrawBuffer->Visual.depthBits <= 16) 373fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.z = FloatToFixed(vert->attrib[FRAG_ATTRIB_WPOS][2] + 0.5F); 374fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian else 375fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.z = (GLuint) (vert->attrib[FRAG_ATTRIB_WPOS][2] + 0.5F); 376fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.zStep = 0; 377fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 3780fd679a1903d997b53fe20b86821a58c1a66262fBrian size = get_size(ctx, vert, GL_FALSE); 379e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 380fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /* span init */ 381f4b103dc993491355ec3e3640d9cb060138175c2Brian INIT_SPAN(span, GL_POINT); 382fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.arrayMask = SPAN_XY; 383fcd7c37fd3d0f61cf6ac81170bc0b3fca64ad9bbBrian span.facing = swrast->PointLineFacing; 384e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 385dbe901ceb01e48ba7d79fd9245b9d339ef17c692Ian Romanick span.interpMask = SPAN_Z | SPAN_RGBA; 386dbe901ceb01e48ba7d79fd9245b9d339ef17c692Ian Romanick span.red = ChanToFixed(vert->color[0]); 387dbe901ceb01e48ba7d79fd9245b9d339ef17c692Ian Romanick span.green = ChanToFixed(vert->color[1]); 388dbe901ceb01e48ba7d79fd9245b9d339ef17c692Ian Romanick span.blue = ChanToFixed(vert->color[2]); 389dbe901ceb01e48ba7d79fd9245b9d339ef17c692Ian Romanick span.alpha = ChanToFixed(vert->color[3]); 390dbe901ceb01e48ba7d79fd9245b9d339ef17c692Ian Romanick span.redStep = 0; 391dbe901ceb01e48ba7d79fd9245b9d339ef17c692Ian Romanick span.greenStep = 0; 392dbe901ceb01e48ba7d79fd9245b9d339ef17c692Ian Romanick span.blueStep = 0; 393dbe901ceb01e48ba7d79fd9245b9d339ef17c692Ian Romanick span.alphaStep = 0; 394e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 395fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /* need these for fragment programs */ 396fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.attrStart[FRAG_ATTRIB_WPOS][3] = 1.0F; 397fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0F; 398fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0F; 399fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 400fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian ATTRIB_LOOP_BEGIN 401fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian COPY_4V(span.attrStart[attr], vert->attrib[attr]); 402fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian ASSIGN_4V(span.attrStepX[attr], 0, 0, 0, 0); 403fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian ASSIGN_4V(span.attrStepY[attr], 0, 0, 0, 0); 404fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian ATTRIB_LOOP_END 405fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 406fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /* compute pos, bounds and render */ 407fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian { 408fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian const GLfloat x = vert->attrib[FRAG_ATTRIB_WPOS][0]; 409fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian const GLfloat y = vert->attrib[FRAG_ATTRIB_WPOS][1]; 410fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian GLint iSize = (GLint) (size + 0.5F); 411fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian GLint xmin, xmax, ymin, ymax, ix, iy; 412fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian GLint iRadius; 413fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 414fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian iSize = MAX2(1, iSize); 415fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian iRadius = iSize / 2; 416fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 417fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian if (iSize & 1) { 418fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /* odd size */ 419fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian xmin = (GLint) (x - iRadius); 420fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian xmax = (GLint) (x + iRadius); 421fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian ymin = (GLint) (y - iRadius); 422fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian ymax = (GLint) (y + iRadius); 423fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian } 424fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian else { 425fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /* even size */ 4264f9d29cd4e876cd202a7d3e81f6d91fc7f9625a2Brian /* 0.501 factor allows conformance to pass */ 4274f9d29cd4e876cd202a7d3e81f6d91fc7f9625a2Brian xmin = (GLint) (x + 0.501) - iRadius; 428fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian xmax = xmin + iSize - 1; 4294f9d29cd4e876cd202a7d3e81f6d91fc7f9625a2Brian ymin = (GLint) (y + 0.501) - iRadius; 430fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian ymax = ymin + iSize - 1; 431fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian } 432e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 433fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /* generate fragments */ 434fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.end = 0; 435fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian for (iy = ymin; iy <= ymax; iy++) { 436fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian for (ix = xmin; ix <= xmax; ix++) { 437fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.array->x[span.end] = ix; 438fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.array->y[span.end] = iy; 439fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span.end++; 440fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian } 441fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian } 44247d88ef204b42a9220c6be3e98c92df9c9aa0860Brian Paul assert(span.end <= SWRAST_MAX_WIDTH); 443fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian _swrast_write_rgba_span(ctx, &span); 444fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian } 445fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian} 446e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 447e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 448fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian/** 449fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian * Draw size=1, single-pixel point 450e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 451fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brianstatic void 452f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergpixel_point(struct gl_context *ctx, const SWvertex *vert) 453fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian{ 454fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian SWcontext *swrast = SWRAST_CONTEXT(ctx); 455fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /* 456fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian * Note that unlike the other functions, we put single-pixel points 457fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian * into a special span array in order to render as many points as 458fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian * possible with a single _swrast_write_rgba_span() call. 459fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian */ 460fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian SWspan *span = &(swrast->PointSpan); 461fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian GLuint count; 462fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 463fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian CULL_INVALID(vert); 464fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 465fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /* Span init */ 466fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span->interpMask = 0; 467fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span->arrayMask = SPAN_XY | SPAN_Z; 468dbe901ceb01e48ba7d79fd9245b9d339ef17c692Ian Romanick span->arrayMask |= SPAN_RGBA; 469fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /*span->arrayMask |= SPAN_LAMBDA;*/ 470fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span->arrayAttribs = swrast->_ActiveAttribMask; /* we'll produce these vals */ 471fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 472fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /* need these for fragment programs */ 473fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span->attrStart[FRAG_ATTRIB_WPOS][3] = 1.0F; 474fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span->attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0F; 475fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span->attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0F; 476fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian 477fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /* check if we need to flush */ 47847d88ef204b42a9220c6be3e98c92df9c9aa0860Brian Paul if (span->end >= SWRAST_MAX_WIDTH || 479fcd7c37fd3d0f61cf6ac81170bc0b3fca64ad9bbBrian (swrast->_RasterMask & (BLEND_BIT | LOGIC_OP_BIT | MASKING_BIT)) || 480fcd7c37fd3d0f61cf6ac81170bc0b3fca64ad9bbBrian span->facing != swrast->PointLineFacing) { 48148aa35a8b28e2cd5dab994c2cc0d728275b9aad2Brian if (span->end > 0) { 482dbe901ceb01e48ba7d79fd9245b9d339ef17c692Ian Romanick _swrast_write_rgba_span(ctx, span); 48348aa35a8b28e2cd5dab994c2cc0d728275b9aad2Brian span->end = 0; 48448aa35a8b28e2cd5dab994c2cc0d728275b9aad2Brian } 485fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian } 486e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 487fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian count = span->end; 488e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 489fcd7c37fd3d0f61cf6ac81170bc0b3fca64ad9bbBrian span->facing = swrast->PointLineFacing; 490fcd7c37fd3d0f61cf6ac81170bc0b3fca64ad9bbBrian 491fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /* fragment attributes */ 492dbe901ceb01e48ba7d79fd9245b9d339ef17c692Ian Romanick span->array->rgba[count][RCOMP] = vert->color[0]; 493dbe901ceb01e48ba7d79fd9245b9d339ef17c692Ian Romanick span->array->rgba[count][GCOMP] = vert->color[1]; 494dbe901ceb01e48ba7d79fd9245b9d339ef17c692Ian Romanick span->array->rgba[count][BCOMP] = vert->color[2]; 495dbe901ceb01e48ba7d79fd9245b9d339ef17c692Ian Romanick span->array->rgba[count][ACOMP] = vert->color[3]; 496dbe901ceb01e48ba7d79fd9245b9d339ef17c692Ian Romanick 497fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian ATTRIB_LOOP_BEGIN 498fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian COPY_4V(span->array->attribs[attr][count], vert->attrib[attr]); 499fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian ATTRIB_LOOP_END 50006d05afdd687fcd1d59d46c6a86c2e5707e1859bBrian Paul 501fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian /* fragment position */ 502fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span->array->x[count] = (GLint) vert->attrib[FRAG_ATTRIB_WPOS][0]; 503fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span->array->y[count] = (GLint) vert->attrib[FRAG_ATTRIB_WPOS][1]; 504fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span->array->z[count] = (GLint) (vert->attrib[FRAG_ATTRIB_WPOS][2] + 0.5F); 50506d05afdd687fcd1d59d46c6a86c2e5707e1859bBrian Paul 506fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian span->end = count + 1; 50747d88ef204b42a9220c6be3e98c92df9c9aa0860Brian Paul ASSERT(span->end <= SWRAST_MAX_WIDTH); 508fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian} 50906d05afdd687fcd1d59d46c6a86c2e5707e1859bBrian Paul 51006d05afdd687fcd1d59d46c6a86c2e5707e1859bBrian Paul 511fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian/** 512fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian * Add specular color to primary color, draw point, restore original 513fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian * primary color. 514fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian */ 5159e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrianvoid 516f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_swrast_add_spec_terms_point(struct gl_context *ctx, const SWvertex *v0) 51746b0988c673b28e072fd0cbf477632a9ab6f9f18Keith Whitwell{ 518fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian SWvertex *ncv0 = (SWvertex *) v0; /* cast away const */ 5199e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLfloat rSum, gSum, bSum; 5209e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLchan cSave[4]; 5219e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian 5229e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* save */ 523fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian COPY_CHAN4(cSave, ncv0->color); 5249e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* sum */ 5259e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian rSum = CHAN_TO_FLOAT(ncv0->color[0]) + ncv0->attrib[FRAG_ATTRIB_COL1][0]; 5269e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian gSum = CHAN_TO_FLOAT(ncv0->color[1]) + ncv0->attrib[FRAG_ATTRIB_COL1][1]; 5279e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian bSum = CHAN_TO_FLOAT(ncv0->color[2]) + ncv0->attrib[FRAG_ATTRIB_COL1][2]; 5289e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[0], rSum); 5299e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[1], gSum); 5309e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[2], bSum); 5319e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* draw */ 5329e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian SWRAST_CONTEXT(ctx)->SpecPoint(ctx, ncv0); 5339e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* restore */ 5349e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian COPY_CHAN4(ncv0->color, cSave); 53546b0988c673b28e072fd0cbf477632a9ab6f9f18Keith Whitwell} 53646b0988c673b28e072fd0cbf477632a9ab6f9f18Keith Whitwell 53746b0988c673b28e072fd0cbf477632a9ab6f9f18Keith Whitwell 538fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian/** 539fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian * Examine current state to determine which point drawing function to use. 540e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 54122144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughesvoid 542f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_swrast_choose_point(struct gl_context *ctx) 543e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 544cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell SWcontext *swrast = SWRAST_CONTEXT(ctx); 545228f20e324249ef25beed725a6a821e0bd0cc232Brian Paul const GLfloat size = CLAMP(ctx->Point.Size, 546228f20e324249ef25beed725a6a821e0bd0cc232Brian Paul ctx->Point.MinSize, 547228f20e324249ef25beed725a6a821e0bd0cc232Brian Paul ctx->Point.MaxSize); 5481d52b6aaf41b32aaf8d1cdf5a3cd5ff4ecba28f4Brian 549fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian if (ctx->RenderMode == GL_RENDER) { 5506c408b46678637959dba04663fbc34eb9c4bc397Brian Paul if (ctx->Point.PointSprite) { 551fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian swrast->Point = sprite_point; 5522fd9c8690fa86b17c42afcc73307d2232b8f79f6Brian Paul } 553fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian else if (ctx->Point.SmoothFlag) { 554fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian swrast->Point = smooth_point; 5552fd9c8690fa86b17c42afcc73307d2232b8f79f6Brian Paul } 556228f20e324249ef25beed725a6a821e0bd0cc232Brian Paul else if (size > 1.0 || 557fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian ctx->Point._Attenuated || 558fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian ctx->VertexProgram.PointSizeEnabled) { 559fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian swrast->Point = large_point; 560e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 561e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 562fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian swrast->Point = pixel_point; 5632fd9c8690fa86b17c42afcc73307d2232b8f79f6Brian Paul } 564e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 565fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian else if (ctx->RenderMode == GL_FEEDBACK) { 566fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian swrast->Point = _swrast_feedback_point; 567e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 568e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 569e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* GL_SELECT mode */ 570fc5bf536440efeb9766cc1fd6e69642bc27afbd8Brian swrast->Point = _swrast_select_point; 571e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 572e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 573