Fixed typo
[reactos.git] / dll / opengl / mesa / main / polygon.c
1 /**
2 * \file polygon.c
3 * Polygon operations.
4 */
5
6 /*
7 * Mesa 3-D graphics library
8 * Version: 6.5.1
9 *
10 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
11 *
12 * Permission is hereby granted, free of charge, to any person obtaining a
13 * copy of this software and associated documentation files (the "Software"),
14 * to deal in the Software without restriction, including without limitation
15 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 * and/or sell copies of the Software, and to permit persons to whom the
17 * Software is furnished to do so, subject to the following conditions:
18 *
19 * The above copyright notice and this permission notice shall be included
20 * in all copies or substantial portions of the Software.
21 *
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
26 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
27 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 */
29
30 #include <precomp.h>
31
32 /**
33 * Specify whether to cull front- or back-facing facets.
34 *
35 * \param mode culling mode.
36 *
37 * \sa glCullFace().
38 *
39 * Verifies the parameter and updates gl_polygon_attrib::CullFaceMode. On
40 * change, flushes the vertices and notifies the driver via
41 * the dd_function_table::CullFace callback.
42 */
43 void GLAPIENTRY
44 _mesa_CullFace( GLenum mode )
45 {
46 GET_CURRENT_CONTEXT(ctx);
47 ASSERT_OUTSIDE_BEGIN_END(ctx);
48
49 if (MESA_VERBOSE&VERBOSE_API)
50 _mesa_debug(ctx, "glCullFace %s\n", _mesa_lookup_enum_by_nr(mode));
51
52 if (mode!=GL_FRONT && mode!=GL_BACK && mode!=GL_FRONT_AND_BACK) {
53 _mesa_error( ctx, GL_INVALID_ENUM, "glCullFace" );
54 return;
55 }
56
57 if (ctx->Polygon.CullFaceMode == mode)
58 return;
59
60 FLUSH_VERTICES(ctx, _NEW_POLYGON);
61 ctx->Polygon.CullFaceMode = mode;
62
63 if (ctx->Driver.CullFace)
64 ctx->Driver.CullFace( ctx, mode );
65 }
66
67
68 /**
69 * Define front- and back-facing
70 *
71 * \param mode orientation of front-facing polygons.
72 *
73 * \sa glFrontFace().
74 *
75 * Verifies the parameter and updates gl_polygon_attrib::FrontFace. On change
76 * flushes the vertices and notifies the driver via
77 * the dd_function_table::FrontFace callback.
78 */
79 void GLAPIENTRY
80 _mesa_FrontFace( GLenum mode )
81 {
82 GET_CURRENT_CONTEXT(ctx);
83 ASSERT_OUTSIDE_BEGIN_END(ctx);
84
85 if (MESA_VERBOSE&VERBOSE_API)
86 _mesa_debug(ctx, "glFrontFace %s\n", _mesa_lookup_enum_by_nr(mode));
87
88 if (mode!=GL_CW && mode!=GL_CCW) {
89 _mesa_error( ctx, GL_INVALID_ENUM, "glFrontFace" );
90 return;
91 }
92
93 if (ctx->Polygon.FrontFace == mode)
94 return;
95
96 FLUSH_VERTICES(ctx, _NEW_POLYGON);
97 ctx->Polygon.FrontFace = mode;
98
99 ctx->Polygon._FrontBit = (GLboolean) (mode == GL_CW);
100
101 if (ctx->Driver.FrontFace)
102 ctx->Driver.FrontFace( ctx, mode );
103 }
104
105
106 /**
107 * Set the polygon rasterization mode.
108 *
109 * \param face the polygons which \p mode applies to.
110 * \param mode how polygons should be rasterized.
111 *
112 * \sa glPolygonMode().
113 *
114 * Verifies the parameters and updates gl_polygon_attrib::FrontMode and
115 * gl_polygon_attrib::BackMode. On change flushes the vertices and notifies the
116 * driver via the dd_function_table::PolygonMode callback.
117 */
118 void GLAPIENTRY
119 _mesa_PolygonMode( GLenum face, GLenum mode )
120 {
121 GET_CURRENT_CONTEXT(ctx);
122 ASSERT_OUTSIDE_BEGIN_END(ctx);
123
124 if (MESA_VERBOSE&VERBOSE_API)
125 _mesa_debug(ctx, "glPolygonMode %s %s\n",
126 _mesa_lookup_enum_by_nr(face),
127 _mesa_lookup_enum_by_nr(mode));
128
129 if (mode!=GL_POINT && mode!=GL_LINE && mode!=GL_FILL) {
130 _mesa_error( ctx, GL_INVALID_ENUM, "glPolygonMode(mode)" );
131 return;
132 }
133
134 switch (face) {
135 case GL_FRONT:
136 if (ctx->Polygon.FrontMode == mode)
137 return;
138 FLUSH_VERTICES(ctx, _NEW_POLYGON);
139 ctx->Polygon.FrontMode = mode;
140 break;
141 case GL_FRONT_AND_BACK:
142 if (ctx->Polygon.FrontMode == mode &&
143 ctx->Polygon.BackMode == mode)
144 return;
145 FLUSH_VERTICES(ctx, _NEW_POLYGON);
146 ctx->Polygon.FrontMode = mode;
147 ctx->Polygon.BackMode = mode;
148 break;
149 case GL_BACK:
150 if (ctx->Polygon.BackMode == mode)
151 return;
152 FLUSH_VERTICES(ctx, _NEW_POLYGON);
153 ctx->Polygon.BackMode = mode;
154 break;
155 default:
156 _mesa_error( ctx, GL_INVALID_ENUM, "glPolygonMode(face)" );
157 return;
158 }
159
160 if (ctx->Polygon.FrontMode == GL_FILL && ctx->Polygon.BackMode == GL_FILL)
161 ctx->_TriangleCaps &= ~DD_TRI_UNFILLED;
162 else
163 ctx->_TriangleCaps |= DD_TRI_UNFILLED;
164
165 if (ctx->Driver.PolygonMode)
166 ctx->Driver.PolygonMode(ctx, face, mode);
167 }
168
169 #if _HAVE_FULL_GL
170
171
172 /**
173 * This routine updates the ctx->Polygon.Stipple state.
174 * If we're getting the stipple data from a PBO, we map the buffer
175 * in order to access the data.
176 * In any case, we obey the current pixel unpacking parameters when fetching
177 * the stipple data.
178 *
179 * In the future, this routine should be used as a fallback, called via
180 * ctx->Driver.PolygonStipple(). We'll have to update all the DRI drivers
181 * too.
182 */
183 void
184 _mesa_polygon_stipple(struct gl_context *ctx, const GLubyte *pattern)
185 {
186 if (!pattern)
187 return;
188
189 _mesa_unpack_polygon_stipple(pattern, ctx->PolygonStipple, &ctx->Unpack);
190 }
191
192
193 /**
194 * Called by glPolygonStipple.
195 */
196 void GLAPIENTRY
197 _mesa_PolygonStipple( const GLubyte *pattern )
198 {
199 GET_CURRENT_CONTEXT(ctx);
200 ASSERT_OUTSIDE_BEGIN_END(ctx);
201
202 if (MESA_VERBOSE&VERBOSE_API)
203 _mesa_debug(ctx, "glPolygonStipple\n");
204
205 FLUSH_VERTICES(ctx, _NEW_POLYGONSTIPPLE);
206
207 _mesa_polygon_stipple(ctx, pattern);
208
209 if (ctx->Driver.PolygonStipple)
210 ctx->Driver.PolygonStipple(ctx, pattern);
211 }
212
213
214 /**
215 * Called by glPolygonStipple.
216 */
217 void GLAPIENTRY
218 _mesa_GetPolygonStipple( GLubyte *dest )
219 {
220 GET_CURRENT_CONTEXT(ctx);
221 ASSERT_OUTSIDE_BEGIN_END(ctx);
222
223 if (MESA_VERBOSE&VERBOSE_API)
224 _mesa_debug(ctx, "glGetPolygonStipple\n");
225 if (!dest)
226 return;
227
228 _mesa_pack_polygon_stipple(ctx->PolygonStipple, dest, &ctx->Pack);
229 }
230
231
232 void GLAPIENTRY
233 _mesa_PolygonOffset( GLfloat factor, GLfloat units )
234 {
235 GET_CURRENT_CONTEXT(ctx);
236 ASSERT_OUTSIDE_BEGIN_END(ctx);
237
238 if (MESA_VERBOSE&VERBOSE_API)
239 _mesa_debug(ctx, "glPolygonOffset %f %f\n", factor, units);
240
241 if (ctx->Polygon.OffsetFactor == factor &&
242 ctx->Polygon.OffsetUnits == units)
243 return;
244
245 FLUSH_VERTICES(ctx, _NEW_POLYGON);
246 ctx->Polygon.OffsetFactor = factor;
247 ctx->Polygon.OffsetUnits = units;
248
249 if (ctx->Driver.PolygonOffset)
250 ctx->Driver.PolygonOffset( ctx, factor, units );
251 }
252
253
254 void GLAPIENTRY
255 _mesa_PolygonOffsetEXT( GLfloat factor, GLfloat bias )
256 {
257 GET_CURRENT_CONTEXT(ctx);
258 /* XXX mult by DepthMaxF here??? */
259 _mesa_PolygonOffset(factor, bias * ctx->DrawBuffer->_DepthMaxF );
260 }
261
262 #endif
263
264
265 /**********************************************************************/
266 /** \name Initialization */
267 /*@{*/
268
269 /**
270 * Initialize the context polygon state.
271 *
272 * \param ctx GL context.
273 *
274 * Initializes __struct gl_contextRec::Polygon and __struct gl_contextRec::PolygonStipple
275 * attribute groups.
276 */
277 void _mesa_init_polygon( struct gl_context * ctx )
278 {
279 /* Polygon group */
280 ctx->Polygon.CullFlag = GL_FALSE;
281 ctx->Polygon.CullFaceMode = GL_BACK;
282 ctx->Polygon.FrontFace = GL_CCW;
283 ctx->Polygon._FrontBit = 0;
284 ctx->Polygon.FrontMode = GL_FILL;
285 ctx->Polygon.BackMode = GL_FILL;
286 ctx->Polygon.SmoothFlag = GL_FALSE;
287 ctx->Polygon.StippleFlag = GL_FALSE;
288 ctx->Polygon.OffsetFactor = 0.0F;
289 ctx->Polygon.OffsetUnits = 0.0F;
290 ctx->Polygon.OffsetPoint = GL_FALSE;
291 ctx->Polygon.OffsetLine = GL_FALSE;
292 ctx->Polygon.OffsetFill = GL_FALSE;
293
294
295 /* Polygon Stipple group */
296 memset( ctx->PolygonStipple, 0xff, 32*sizeof(GLuint) );
297 }
298
299 /*@}*/