2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2007 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.
33 * \param ix - integer fragment window X coordiante
34 * \param iy - integer fragment window Y coordiante
37 NAME(plot
)(GLcontext
*ctx
, struct LineInfo
*line
, int ix
, int iy
)
39 const SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
40 const GLfloat fx
= (GLfloat
) ix
;
41 const GLfloat fy
= (GLfloat
) iy
;
43 const GLfloat coverage
= compute_coveragei(line
, ix
, iy
);
45 const GLfloat coverage
= compute_coveragef(line
, ix
, iy
);
47 const GLuint i
= line
->span
.end
;
55 line
->span
.array
->coverage
[i
] = coverage
;
56 line
->span
.array
->x
[i
] = ix
;
57 line
->span
.array
->y
[i
] = iy
;
60 * Compute Z, color, texture coords, fog for the fragment by
61 * solving the plane equations at (ix,iy).
64 line
->span
.array
->z
[i
] = (GLuint
) solve_plane(fx
, fy
, line
->zPlane
);
67 line
->span
.array
->rgba
[i
][RCOMP
] = solve_plane_chan(fx
, fy
, line
->rPlane
);
68 line
->span
.array
->rgba
[i
][GCOMP
] = solve_plane_chan(fx
, fy
, line
->gPlane
);
69 line
->span
.array
->rgba
[i
][BCOMP
] = solve_plane_chan(fx
, fy
, line
->bPlane
);
70 line
->span
.array
->rgba
[i
][ACOMP
] = solve_plane_chan(fx
, fy
, line
->aPlane
);
73 line
->span
.array
->index
[i
] = (GLint
) solve_plane(fx
, fy
, line
->iPlane
);
75 #if defined(DO_ATTRIBS)
77 GLfloat (*attribArray
)[4] = line
->span
.array
->attribs
[attr
];
78 if (attr
>= FRAG_ATTRIB_TEX0
&& attr
< FRAG_ATTRIB_VAR0
79 && !ctx
->FragmentProgram
._Active
) {
80 /* texcoord w/ divide by Q */
81 const GLuint unit
= attr
- FRAG_ATTRIB_TEX0
;
82 const GLfloat invQ
= solve_plane_recip(fx
, fy
, line
->attrPlane
[attr
][3]);
84 for (c
= 0; c
< 3; c
++) {
85 attribArray
[i
][c
] = solve_plane(fx
, fy
, line
->attrPlane
[attr
][c
]) * invQ
;
87 line
->span
.array
->lambda
[unit
][i
]
88 = compute_lambda(line
->attrPlane
[attr
][0],
89 line
->attrPlane
[attr
][1], invQ
,
90 line
->texWidth
[attr
], line
->texHeight
[attr
]);
93 /* non-texture attrib */
94 const GLfloat invW
= solve_plane_recip(fx
, fy
, line
->wPlane
);
96 for (c
= 0; c
< 4; c
++) {
97 attribArray
[i
][c
] = solve_plane(fx
, fy
, line
->attrPlane
[attr
][c
]) * invW
;
103 if (line
->span
.end
== MAX_WIDTH
) {
105 _swrast_write_rgba_span(ctx
, &(line
->span
));
107 _swrast_write_index_span(ctx
, &(line
->span
));
109 line
->span
.end
= 0; /* reset counter */
119 NAME(line
)(GLcontext
*ctx
, const SWvertex
*v0
, const SWvertex
*v1
)
121 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
122 GLfloat tStart
, tEnd
; /* segment start, end along line length */
126 /* Init the LineInfo struct */
127 struct LineInfo line
;
128 line
.x0
= v0
->attrib
[FRAG_ATTRIB_WPOS
][0];
129 line
.y0
= v0
->attrib
[FRAG_ATTRIB_WPOS
][1];
130 line
.x1
= v1
->attrib
[FRAG_ATTRIB_WPOS
][0];
131 line
.y1
= v1
->attrib
[FRAG_ATTRIB_WPOS
][1];
132 line
.dx
= line
.x1
- line
.x0
;
133 line
.dy
= line
.y1
- line
.y0
;
134 line
.len
= SQRTF(line
.dx
* line
.dx
+ line
.dy
* line
.dy
);
135 line
.halfWidth
= 0.5F
* CLAMP(ctx
->Line
.Width
,
136 ctx
->Const
.MinLineWidthAA
,
137 ctx
->Const
.MaxLineWidthAA
);
139 if (line
.len
== 0.0 || IS_INF_OR_NAN(line
.len
))
142 INIT_SPAN(line
.span
, GL_LINE
);
143 line
.span
.arrayMask
= SPAN_XY
| SPAN_COVERAGE
;
144 line
.span
.facing
= swrast
->PointLineFacing
;
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
->attrib
[FRAG_ATTRIB_WPOS
][2], v1
->attrib
[FRAG_ATTRIB_WPOS
][2], line
.zPlane
);
154 line
.span
.arrayMask
|= SPAN_RGBA
;
155 if (ctx
->Light
.ShadeModel
== GL_SMOOTH
) {
156 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
,
157 v0
->color
[RCOMP
], v1
->color
[RCOMP
], line
.rPlane
);
158 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
,
159 v0
->color
[GCOMP
], v1
->color
[GCOMP
], line
.gPlane
);
160 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
,
161 v0
->color
[BCOMP
], v1
->color
[BCOMP
], line
.bPlane
);
162 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
,
163 v0
->color
[ACOMP
], v1
->color
[ACOMP
], line
.aPlane
);
166 constant_plane(v1
->color
[RCOMP
], line
.rPlane
);
167 constant_plane(v1
->color
[GCOMP
], line
.gPlane
);
168 constant_plane(v1
->color
[BCOMP
], line
.bPlane
);
169 constant_plane(v1
->color
[ACOMP
], line
.aPlane
);
173 line
.span
.arrayMask
|= SPAN_INDEX
;
174 if (ctx
->Light
.ShadeModel
== GL_SMOOTH
) {
175 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
,
176 v0
->attrib
[FRAG_ATTRIB_CI
][0],
177 v1
->attrib
[FRAG_ATTRIB_CI
][0], line
.iPlane
);
180 constant_plane(v1
->attrib
[FRAG_ATTRIB_CI
][0], line
.iPlane
);
183 #if defined(DO_ATTRIBS)
185 const GLfloat invW0
= v0
->attrib
[FRAG_ATTRIB_WPOS
][3];
186 const GLfloat invW1
= v1
->attrib
[FRAG_ATTRIB_WPOS
][3];
187 line
.span
.arrayMask
|= SPAN_LAMBDA
;
188 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
, invW0
, invW1
, line
.wPlane
);
191 if (swrast
->_InterpMode
[attr
] == GL_FLAT
) {
192 for (c
= 0; c
< 4; c
++) {
193 constant_plane(v1
->attrib
[attr
][c
], line
.attrPlane
[attr
][c
]);
197 for (c
= 0; c
< 4; c
++) {
198 const GLfloat a0
= v0
->attrib
[attr
][c
] * invW0
;
199 const GLfloat a1
= v1
->attrib
[attr
][c
] * invW1
;
200 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
, a0
, a1
,
201 line
.attrPlane
[attr
][c
]);
204 line
.span
.arrayAttribs
|= (1 << attr
);
205 if (attr
>= FRAG_ATTRIB_TEX0
&& attr
< FRAG_ATTRIB_VAR0
) {
206 const GLuint u
= attr
- FRAG_ATTRIB_TEX0
;
207 const struct gl_texture_object
*obj
= ctx
->Texture
.Unit
[u
]._Current
;
208 const struct gl_texture_image
*texImage
= obj
->Image
[0][obj
->BaseLevel
];
209 line
.texWidth
[attr
] = (GLfloat
) texImage
->Width
;
210 line
.texHeight
[attr
] = (GLfloat
) texImage
->Height
;
217 inSegment
= GL_FALSE
;
218 iLen
= (GLint
) line
.len
;
220 if (ctx
->Line
.StippleFlag
) {
221 for (i
= 0; i
< iLen
; i
++) {
222 const GLuint bit
= (swrast
->StippleCounter
/ ctx
->Line
.StippleFactor
) & 0xf;
223 if ((1 << bit
) & ctx
->Line
.StipplePattern
) {
224 /* stipple bit is on */
225 const GLfloat t
= (GLfloat
) i
/ (GLfloat
) line
.len
;
227 /* start new segment */
232 /* still in the segment, extend it */
237 /* stipple bit is off */
238 if (inSegment
&& (tEnd
> tStart
)) {
239 /* draw the segment */
240 segment(ctx
, &line
, NAME(plot
), tStart
, tEnd
);
241 inSegment
= GL_FALSE
;
244 /* still between segments, do nothing */
247 swrast
->StippleCounter
++;
251 /* draw the final segment of the line */
252 segment(ctx
, &line
, NAME(plot
), tStart
, 1.0F
);
257 segment(ctx
, &line
, NAME(plot
), 0.0, 1.0);
261 _swrast_write_rgba_span(ctx
, &(line
.span
));
263 _swrast_write_index_span(ctx
, &(line
.span
));