Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1901 | serge | 1 | /* |
2 | * Mesa 3-D graphics library |
||
3 | * Version: 7.1 |
||
4 | * |
||
5 | * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. |
||
6 | * |
||
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: |
||
13 | * |
||
14 | * The above copyright notice and this permission notice shall be included |
||
15 | * in all copies or substantial portions of the Software. |
||
16 | * |
||
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. |
||
23 | */ |
||
24 | |||
25 | |||
26 | #include "main/glheader.h" |
||
27 | #include "main/context.h" |
||
28 | #include "main/colormac.h" |
||
29 | #include "main/macros.h" |
||
30 | #include "s_aaline.h" |
||
31 | #include "s_context.h" |
||
32 | #include "s_feedback.h" |
||
33 | #include "s_lines.h" |
||
34 | #include "s_span.h" |
||
35 | |||
36 | |||
37 | /* |
||
38 | * Init the mask[] array to implement a line stipple. |
||
39 | */ |
||
40 | static void |
||
41 | compute_stipple_mask( struct gl_context *ctx, GLuint len, GLubyte mask[] ) |
||
42 | { |
||
43 | SWcontext *swrast = SWRAST_CONTEXT(ctx); |
||
44 | GLuint i; |
||
45 | |||
46 | for (i = 0; i < len; i++) { |
||
47 | GLuint bit = (swrast->StippleCounter / ctx->Line.StippleFactor) & 0xf; |
||
48 | if ((1 << bit) & ctx->Line.StipplePattern) { |
||
49 | mask[i] = GL_TRUE; |
||
50 | } |
||
51 | else { |
||
52 | mask[i] = GL_FALSE; |
||
53 | } |
||
54 | swrast->StippleCounter++; |
||
55 | } |
||
56 | } |
||
57 | |||
58 | |||
59 | /* |
||
60 | * To draw a wide line we can simply redraw the span N times, side by side. |
||
61 | */ |
||
62 | static void |
||
63 | draw_wide_line( struct gl_context *ctx, SWspan *span, GLboolean xMajor ) |
||
64 | { |
||
65 | const GLint width = (GLint) CLAMP(ctx->Line.Width, |
||
66 | ctx->Const.MinLineWidth, |
||
67 | ctx->Const.MaxLineWidth); |
||
68 | GLint start; |
||
69 | |||
70 | ASSERT(span->end < MAX_WIDTH); |
||
71 | |||
72 | if (width & 1) |
||
73 | start = width / 2; |
||
74 | else |
||
75 | start = width / 2 - 1; |
||
76 | |||
77 | if (xMajor) { |
||
78 | GLint *y = span->array->y; |
||
79 | GLuint i; |
||
80 | GLint w; |
||
81 | for (w = 0; w < width; w++) { |
||
82 | if (w == 0) { |
||
83 | for (i = 0; i < span->end; i++) |
||
84 | y[i] -= start; |
||
85 | } |
||
86 | else { |
||
87 | for (i = 0; i < span->end; i++) |
||
88 | y[i]++; |
||
89 | } |
||
90 | _swrast_write_rgba_span(ctx, span); |
||
91 | } |
||
92 | } |
||
93 | else { |
||
94 | GLint *x = span->array->x; |
||
95 | GLuint i; |
||
96 | GLint w; |
||
97 | for (w = 0; w < width; w++) { |
||
98 | if (w == 0) { |
||
99 | for (i = 0; i < span->end; i++) |
||
100 | x[i] -= start; |
||
101 | } |
||
102 | else { |
||
103 | for (i = 0; i < span->end; i++) |
||
104 | x[i]++; |
||
105 | } |
||
106 | _swrast_write_rgba_span(ctx, span); |
||
107 | } |
||
108 | } |
||
109 | } |
||
110 | |||
111 | |||
112 | |||
113 | /**********************************************************************/ |
||
114 | /***** Rasterization *****/ |
||
115 | /**********************************************************************/ |
||
116 | |||
117 | /* Simple RGBA index line (no stipple, width=1, no Z, no fog, no tex)*/ |
||
118 | #define NAME simple_no_z_rgba_line |
||
119 | #define INTERP_RGBA |
||
120 | #define RENDER_SPAN(span) _swrast_write_rgba_span(ctx, &span); |
||
121 | #include "s_linetemp.h" |
||
122 | |||
123 | |||
124 | /* Z, fog, wide, stipple RGBA line */ |
||
125 | #define NAME rgba_line |
||
126 | #define INTERP_RGBA |
||
127 | #define INTERP_Z |
||
128 | #define RENDER_SPAN(span) \ |
||
129 | if (ctx->Line.StippleFlag) { \ |
||
130 | span.arrayMask |= SPAN_MASK; \ |
||
131 | compute_stipple_mask(ctx, span.end, span.array->mask); \ |
||
132 | } \ |
||
133 | if (ctx->Line.Width > 1.0) { \ |
||
134 | draw_wide_line(ctx, &span, (GLboolean)(dx > dy)); \ |
||
135 | } \ |
||
136 | else { \ |
||
137 | _swrast_write_rgba_span(ctx, &span); \ |
||
138 | } |
||
139 | #include "s_linetemp.h" |
||
140 | |||
141 | |||
142 | /* General-purpose line (any/all features). */ |
||
143 | #define NAME general_line |
||
144 | #define INTERP_RGBA |
||
145 | #define INTERP_Z |
||
146 | #define INTERP_ATTRIBS |
||
147 | #define RENDER_SPAN(span) \ |
||
148 | if (ctx->Line.StippleFlag) { \ |
||
149 | span.arrayMask |= SPAN_MASK; \ |
||
150 | compute_stipple_mask(ctx, span.end, span.array->mask); \ |
||
151 | } \ |
||
152 | if (ctx->Line.Width > 1.0) { \ |
||
153 | draw_wide_line(ctx, &span, (GLboolean)(dx > dy)); \ |
||
154 | } \ |
||
155 | else { \ |
||
156 | _swrast_write_rgba_span(ctx, &span); \ |
||
157 | } |
||
158 | #include "s_linetemp.h" |
||
159 | |||
160 | |||
161 | |||
162 | void |
||
163 | _swrast_add_spec_terms_line(struct gl_context *ctx, |
||
164 | const SWvertex *v0, const SWvertex *v1) |
||
165 | { |
||
166 | SWvertex *ncv0 = (SWvertex *)v0; |
||
167 | SWvertex *ncv1 = (SWvertex *)v1; |
||
168 | GLfloat rSum, gSum, bSum; |
||
169 | GLchan cSave[2][4]; |
||
170 | |||
171 | /* save original colors */ |
||
172 | COPY_CHAN4(cSave[0], ncv0->color); |
||
173 | COPY_CHAN4(cSave[1], ncv1->color); |
||
174 | /* sum v0 */ |
||
175 | rSum = CHAN_TO_FLOAT(ncv0->color[0]) + ncv0->attrib[FRAG_ATTRIB_COL1][0]; |
||
176 | gSum = CHAN_TO_FLOAT(ncv0->color[1]) + ncv0->attrib[FRAG_ATTRIB_COL1][1]; |
||
177 | bSum = CHAN_TO_FLOAT(ncv0->color[2]) + ncv0->attrib[FRAG_ATTRIB_COL1][2]; |
||
178 | UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[0], rSum); |
||
179 | UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[1], gSum); |
||
180 | UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[2], bSum); |
||
181 | /* sum v1 */ |
||
182 | rSum = CHAN_TO_FLOAT(ncv1->color[0]) + ncv1->attrib[FRAG_ATTRIB_COL1][0]; |
||
183 | gSum = CHAN_TO_FLOAT(ncv1->color[1]) + ncv1->attrib[FRAG_ATTRIB_COL1][1]; |
||
184 | bSum = CHAN_TO_FLOAT(ncv1->color[2]) + ncv1->attrib[FRAG_ATTRIB_COL1][2]; |
||
185 | UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[0], rSum); |
||
186 | UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[1], gSum); |
||
187 | UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[2], bSum); |
||
188 | /* draw */ |
||
189 | SWRAST_CONTEXT(ctx)->SpecLine( ctx, ncv0, ncv1 ); |
||
190 | /* restore original colors */ |
||
191 | COPY_CHAN4( ncv0->attrib[FRAG_ATTRIB_COL0], cSave[0] ); |
||
192 | COPY_CHAN4( ncv1->attrib[FRAG_ATTRIB_COL0], cSave[1] ); |
||
193 | } |
||
194 | |||
195 | |||
196 | |||
197 | #ifdef DEBUG |
||
198 | |||
199 | /* record the current line function name */ |
||
200 | static const char *lineFuncName = NULL; |
||
201 | |||
202 | #define USE(lineFunc) \ |
||
203 | do { \ |
||
204 | lineFuncName = #lineFunc; \ |
||
205 | /*printf("%s\n", lineFuncName);*/ \ |
||
206 | swrast->Line = lineFunc; \ |
||
207 | } while (0) |
||
208 | |||
209 | #else |
||
210 | |||
211 | #define USE(lineFunc) swrast->Line = lineFunc |
||
212 | |||
213 | #endif |
||
214 | |||
215 | |||
216 | |||
217 | /** |
||
218 | * Determine which line drawing function to use given the current |
||
219 | * rendering context. |
||
220 | * |
||
221 | * Please update the summary flag _SWRAST_NEW_LINE if you add or remove |
||
222 | * tests to this code. |
||
223 | */ |
||
224 | void |
||
225 | _swrast_choose_line( struct gl_context *ctx ) |
||
226 | { |
||
227 | SWcontext *swrast = SWRAST_CONTEXT(ctx); |
||
228 | GLboolean specular = (ctx->Fog.ColorSumEnabled || |
||
229 | (ctx->Light.Enabled && |
||
230 | ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)); |
||
231 | |||
232 | if (ctx->RenderMode == GL_RENDER) { |
||
233 | if (ctx->Line.SmoothFlag) { |
||
234 | /* antialiased lines */ |
||
235 | _swrast_choose_aa_line_function(ctx); |
||
236 | ASSERT(swrast->Line); |
||
237 | } |
||
238 | else if (ctx->Texture._EnabledCoordUnits |
||
239 | || ctx->FragmentProgram._Current |
||
240 | || swrast->_FogEnabled |
||
241 | || specular) { |
||
242 | USE(general_line); |
||
243 | } |
||
244 | else if (ctx->Depth.Test |
||
245 | || ctx->Line.Width != 1.0 |
||
246 | || ctx->Line.StippleFlag) { |
||
247 | /* no texture, but Z, fog, width>1, stipple, etc. */ |
||
248 | #if CHAN_BITS == 32 |
||
249 | USE(general_line); |
||
250 | #else |
||
251 | USE(rgba_line); |
||
252 | #endif |
||
253 | } |
||
254 | else { |
||
255 | ASSERT(!ctx->Depth.Test); |
||
256 | ASSERT(ctx->Line.Width == 1.0); |
||
257 | /* simple lines */ |
||
258 | USE(simple_no_z_rgba_line); |
||
259 | } |
||
260 | } |
||
261 | else if (ctx->RenderMode == GL_FEEDBACK) { |
||
262 | USE(_swrast_feedback_line); |
||
263 | } |
||
264 | else { |
||
265 | ASSERT(ctx->RenderMode == GL_SELECT); |
||
266 | USE(_swrast_select_line); |
||
267 | } |
||
268 | }>>>>>>>><>> |