Subversion Repositories Kolibri OS

Rev

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
}