2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 * Antialiased line template.
32 * Function to render each fragment in the AA line.
35 NAME(plot
)(GLcontext
*ctx
, struct LineInfo
*line
, int ix
, int iy
)
37 const GLfloat fx
= (GLfloat
) ix
;
38 const GLfloat fy
= (GLfloat
) iy
;
40 const GLfloat coverage
= compute_coveragei(line
, ix
, iy
);
42 const GLfloat coverage
= compute_coveragef(line
, ix
, iy
);
44 const GLuint i
= line
->span
.end
;
50 line
->span
.array
->coverage
[i
] = coverage
;
51 line
->span
.array
->x
[i
] = ix
;
52 line
->span
.array
->y
[i
] = iy
;
55 * Compute Z, color, texture coords, fog for the fragment by
56 * solving the plane equations at (ix,iy).
59 line
->span
.array
->z
[i
] = (GLdepth
) IROUND(solve_plane(fx
, fy
, line
->zPlane
));
62 line
->span
.array
->fog
[i
] = solve_plane(fx
, fy
, line
->fPlane
);
65 line
->span
.array
->rgba
[i
][RCOMP
] = solve_plane_chan(fx
, fy
, line
->rPlane
);
66 line
->span
.array
->rgba
[i
][GCOMP
] = solve_plane_chan(fx
, fy
, line
->gPlane
);
67 line
->span
.array
->rgba
[i
][BCOMP
] = solve_plane_chan(fx
, fy
, line
->bPlane
);
68 line
->span
.array
->rgba
[i
][ACOMP
] = solve_plane_chan(fx
, fy
, line
->aPlane
);
71 line
->span
.array
->index
[i
] = (GLint
) solve_plane(fx
, fy
, line
->iPlane
);
74 line
->span
.array
->spec
[i
][RCOMP
] = solve_plane_chan(fx
, fy
, line
->srPlane
);
75 line
->span
.array
->spec
[i
][GCOMP
] = solve_plane_chan(fx
, fy
, line
->sgPlane
);
76 line
->span
.array
->spec
[i
][BCOMP
] = solve_plane_chan(fx
, fy
, line
->sbPlane
);
80 const GLfloat invQ
= solve_plane_recip(fx
, fy
, line
->vPlane
[0]);
81 line
->span
.array
->texcoords
[0][i
][0] = solve_plane(fx
, fy
, line
->sPlane
[0]) * invQ
;
82 line
->span
.array
->texcoords
[0][i
][1] = solve_plane(fx
, fy
, line
->tPlane
[0]) * invQ
;
83 line
->span
.array
->texcoords
[0][i
][2] = solve_plane(fx
, fy
, line
->uPlane
[0]) * invQ
;
84 line
->span
.array
->lambda
[0][i
] = compute_lambda(line
->sPlane
[0], line
->tPlane
[0], invQ
,
85 line
->texWidth
[0], line
->texHeight
[0]);
87 #elif defined(DO_MULTITEX)
90 for (unit
= 0; unit
< ctx
->Const
.MaxTextureUnits
; unit
++) {
91 if (ctx
->Texture
.Unit
[unit
]._ReallyEnabled
) {
92 const GLfloat invQ
= solve_plane_recip(fx
, fy
, line
->vPlane
[unit
]);
93 line
->span
.array
->texcoords
[unit
][i
][0] = solve_plane(fx
, fy
, line
->sPlane
[unit
]) * invQ
;
94 line
->span
.array
->texcoords
[unit
][i
][1] = solve_plane(fx
, fy
, line
->tPlane
[unit
]) * invQ
;
95 line
->span
.array
->texcoords
[unit
][i
][2] = solve_plane(fx
, fy
, line
->uPlane
[unit
]) * invQ
;
96 line
->span
.array
->lambda
[unit
][i
] = compute_lambda(line
->sPlane
[unit
],
97 line
->tPlane
[unit
], invQ
,
98 line
->texWidth
[unit
], line
->texHeight
[unit
]);
104 if (line
->span
.end
== MAX_WIDTH
) {
105 #if defined(DO_TEX) || defined(DO_MULTITEX)
106 _swrast_write_texture_span(ctx
, &(line
->span
));
107 #elif defined(DO_RGBA)
108 _swrast_write_rgba_span(ctx
, &(line
->span
));
110 _swrast_write_index_span(ctx
, &(line
->span
));
112 line
->span
.end
= 0; /* reset counter */
122 NAME(line
)(GLcontext
*ctx
, const SWvertex
*v0
, const SWvertex
*v1
)
124 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
125 GLfloat tStart
, tEnd
; /* segment start, end along line length */
129 /* Init the LineInfo struct */
130 struct LineInfo line
;
131 line
.x0
= v0
->win
[0];
132 line
.y0
= v0
->win
[1];
133 line
.x1
= v1
->win
[0];
134 line
.y1
= v1
->win
[1];
135 line
.dx
= line
.x1
- line
.x0
;
136 line
.dy
= line
.y1
- line
.y0
;
137 line
.len
= SQRTF(line
.dx
* line
.dx
+ line
.dy
* line
.dy
);
138 line
.halfWidth
= 0.5F
* ctx
->Line
.Width
;
140 if (line
.len
== 0.0 || IS_INF_OR_NAN(line
.len
))
143 INIT_SPAN(line
.span
, GL_LINE
, 0, 0, SPAN_XY
| SPAN_COVERAGE
);
145 line
.xAdj
= line
.dx
/ line
.len
* line
.halfWidth
;
146 line
.yAdj
= line
.dy
/ line
.len
* line
.halfWidth
;
149 line
.span
.arrayMask
|= SPAN_Z
;
150 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
,
151 v0
->win
[2], v1
->win
[2], line
.zPlane
);
154 line
.span
.arrayMask
|= SPAN_FOG
;
155 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
,
156 v0
->fog
, v1
->fog
, line
.fPlane
);
159 line
.span
.arrayMask
|= SPAN_RGBA
;
160 if (ctx
->Light
.ShadeModel
== GL_SMOOTH
) {
161 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
,
162 v0
->color
[RCOMP
], v1
->color
[RCOMP
], line
.rPlane
);
163 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
,
164 v0
->color
[GCOMP
], v1
->color
[GCOMP
], line
.gPlane
);
165 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
,
166 v0
->color
[BCOMP
], v1
->color
[BCOMP
], line
.bPlane
);
167 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
,
168 v0
->color
[ACOMP
], v1
->color
[ACOMP
], line
.aPlane
);
171 constant_plane(v1
->color
[RCOMP
], line
.rPlane
);
172 constant_plane(v1
->color
[GCOMP
], line
.gPlane
);
173 constant_plane(v1
->color
[BCOMP
], line
.bPlane
);
174 constant_plane(v1
->color
[ACOMP
], line
.aPlane
);
178 line
.span
.arrayMask
|= SPAN_SPEC
;
179 if (ctx
->Light
.ShadeModel
== GL_SMOOTH
) {
180 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
,
181 v0
->specular
[RCOMP
], v1
->specular
[RCOMP
], line
.srPlane
);
182 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
,
183 v0
->specular
[GCOMP
], v1
->specular
[GCOMP
], line
.sgPlane
);
184 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
,
185 v0
->specular
[BCOMP
], v1
->specular
[BCOMP
], line
.sbPlane
);
188 constant_plane(v1
->specular
[RCOMP
], line
.srPlane
);
189 constant_plane(v1
->specular
[GCOMP
], line
.sgPlane
);
190 constant_plane(v1
->specular
[BCOMP
], line
.sbPlane
);
194 line
.span
.arrayMask
|= SPAN_INDEX
;
195 if (ctx
->Light
.ShadeModel
== GL_SMOOTH
) {
196 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
,
197 v0
->index
, v1
->index
, line
.iPlane
);
200 constant_plane(v1
->index
, line
.iPlane
);
205 const struct gl_texture_object
*obj
= ctx
->Texture
.Unit
[0]._Current
;
206 const struct gl_texture_image
*texImage
= obj
->Image
[0][obj
->BaseLevel
];
207 const GLfloat invW0
= v0
->win
[3];
208 const GLfloat invW1
= v1
->win
[3];
209 const GLfloat s0
= v0
->texcoord
[0][0] * invW0
;
210 const GLfloat s1
= v1
->texcoord
[0][0] * invW1
;
211 const GLfloat t0
= v0
->texcoord
[0][1] * invW0
;
212 const GLfloat t1
= v1
->texcoord
[0][1] * invW0
;
213 const GLfloat r0
= v0
->texcoord
[0][2] * invW0
;
214 const GLfloat r1
= v1
->texcoord
[0][2] * invW0
;
215 const GLfloat q0
= v0
->texcoord
[0][3] * invW0
;
216 const GLfloat q1
= v1
->texcoord
[0][3] * invW0
;
217 line
.span
.arrayMask
|= (SPAN_TEXTURE
| SPAN_LAMBDA
);
218 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
, s0
, s1
, line
.sPlane
[0]);
219 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
, t0
, t1
, line
.tPlane
[0]);
220 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
, r0
, r1
, line
.uPlane
[0]);
221 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
, q0
, q1
, line
.vPlane
[0]);
222 line
.texWidth
[0] = (GLfloat
) texImage
->Width
;
223 line
.texHeight
[0] = (GLfloat
) texImage
->Height
;
225 #elif defined(DO_MULTITEX)
228 line
.span
.arrayMask
|= (SPAN_TEXTURE
| SPAN_LAMBDA
);
229 for (u
= 0; u
< ctx
->Const
.MaxTextureUnits
; u
++) {
230 if (ctx
->Texture
.Unit
[u
]._ReallyEnabled
) {
231 const struct gl_texture_object
*obj
= ctx
->Texture
.Unit
[u
]._Current
;
232 const struct gl_texture_image
*texImage
= obj
->Image
[0][obj
->BaseLevel
];
233 const GLfloat invW0
= v0
->win
[3];
234 const GLfloat invW1
= v1
->win
[3];
235 const GLfloat s0
= v0
->texcoord
[u
][0] * invW0
;
236 const GLfloat s1
= v1
->texcoord
[u
][0] * invW1
;
237 const GLfloat t0
= v0
->texcoord
[u
][1] * invW0
;
238 const GLfloat t1
= v1
->texcoord
[u
][1] * invW0
;
239 const GLfloat r0
= v0
->texcoord
[u
][2] * invW0
;
240 const GLfloat r1
= v1
->texcoord
[u
][2] * invW0
;
241 const GLfloat q0
= v0
->texcoord
[u
][3] * invW0
;
242 const GLfloat q1
= v1
->texcoord
[u
][3] * invW0
;
243 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
, s0
, s1
, line
.sPlane
[u
]);
244 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
, t0
, t1
, line
.tPlane
[u
]);
245 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
, r0
, r1
, line
.uPlane
[u
]);
246 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
, q0
, q1
, line
.vPlane
[u
]);
247 line
.texWidth
[u
] = (GLfloat
) texImage
->Width
;
248 line
.texHeight
[u
] = (GLfloat
) texImage
->Height
;
255 inSegment
= GL_FALSE
;
256 iLen
= (GLint
) line
.len
;
258 if (ctx
->Line
.StippleFlag
) {
259 for (i
= 0; i
< iLen
; i
++) {
260 const GLuint bit
= (swrast
->StippleCounter
/ ctx
->Line
.StippleFactor
) & 0xf;
261 if ((1 << bit
) & ctx
->Line
.StipplePattern
) {
262 /* stipple bit is on */
263 const GLfloat t
= (GLfloat
) i
/ (GLfloat
) line
.len
;
265 /* start new segment */
270 /* still in the segment, extend it */
275 /* stipple bit is off */
276 if (inSegment
&& (tEnd
> tStart
)) {
277 /* draw the segment */
278 segment(ctx
, &line
, NAME(plot
), tStart
, tEnd
);
279 inSegment
= GL_FALSE
;
282 /* still between segments, do nothing */
285 swrast
->StippleCounter
++;
289 /* draw the final segment of the line */
290 segment(ctx
, &line
, NAME(plot
), tStart
, 1.0F
);
295 segment(ctx
, &line
, NAME(plot
), 0.0, 1.0);
298 #if defined(DO_TEX) || defined(DO_MULTITEX)
299 _swrast_write_texture_span(ctx
, &(line
.span
));
300 #elif defined(DO_RGBA)
301 _swrast_write_rgba_span(ctx
, &(line
.span
));
303 _swrast_write_index_span(ctx
, &(line
.span
));