dd4f44ec3630adac02f92c5f45af918cab914b22
[mesa.git] / src / mesa / main / polygon.c
1
2 /*
3 * Mesa 3-D graphics library
4 * Version: 4.1
5 *
6 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26
27 #include "glheader.h"
28 #include "imports.h"
29 #include "context.h"
30 #include "image.h"
31 #include "enums.h"
32 #include "macros.h"
33 #include "polygon.h"
34 #include "mtypes.h"
35
36
37 void
38 _mesa_CullFace( GLenum mode )
39 {
40 GET_CURRENT_CONTEXT(ctx);
41 ASSERT_OUTSIDE_BEGIN_END(ctx);
42
43 if (MESA_VERBOSE&VERBOSE_API)
44 _mesa_debug(ctx, "glCullFace %s\n", _mesa_lookup_enum_by_nr(mode));
45
46 if (mode!=GL_FRONT && mode!=GL_BACK && mode!=GL_FRONT_AND_BACK) {
47 _mesa_error( ctx, GL_INVALID_ENUM, "glCullFace" );
48 return;
49 }
50
51 if (ctx->Polygon.CullFaceMode == mode)
52 return;
53
54 FLUSH_VERTICES(ctx, _NEW_POLYGON);
55 ctx->Polygon.CullFaceMode = mode;
56
57 if (ctx->Driver.CullFace)
58 ctx->Driver.CullFace( ctx, mode );
59 }
60
61
62
63 void
64 _mesa_FrontFace( GLenum mode )
65 {
66 GET_CURRENT_CONTEXT(ctx);
67 ASSERT_OUTSIDE_BEGIN_END(ctx);
68
69 if (MESA_VERBOSE&VERBOSE_API)
70 _mesa_debug(ctx, "glFrontFace %s\n", _mesa_lookup_enum_by_nr(mode));
71
72 if (mode!=GL_CW && mode!=GL_CCW) {
73 _mesa_error( ctx, GL_INVALID_ENUM, "glFrontFace" );
74 return;
75 }
76
77 if (ctx->Polygon.FrontFace == mode)
78 return;
79
80 FLUSH_VERTICES(ctx, _NEW_POLYGON);
81 ctx->Polygon.FrontFace = mode;
82
83 ctx->Polygon._FrontBit = (GLboolean) (mode == GL_CW);
84
85 if (ctx->Driver.FrontFace)
86 ctx->Driver.FrontFace( ctx, mode );
87 }
88
89
90
91 void
92 _mesa_PolygonMode( GLenum face, GLenum mode )
93 {
94 GET_CURRENT_CONTEXT(ctx);
95 ASSERT_OUTSIDE_BEGIN_END(ctx);
96
97 if (MESA_VERBOSE&VERBOSE_API)
98 _mesa_debug(ctx, "glPolygonMode %s %s\n",
99 _mesa_lookup_enum_by_nr(face),
100 _mesa_lookup_enum_by_nr(mode));
101
102 if (mode!=GL_POINT && mode!=GL_LINE && mode!=GL_FILL) {
103 _mesa_error( ctx, GL_INVALID_ENUM, "glPolygonMode(mode)" );
104 return;
105 }
106
107 switch (face) {
108 case GL_FRONT:
109 if (ctx->Polygon.FrontMode == mode)
110 return;
111 FLUSH_VERTICES(ctx, _NEW_POLYGON);
112 ctx->Polygon.FrontMode = mode;
113 break;
114 case GL_FRONT_AND_BACK:
115 if (ctx->Polygon.FrontMode == mode &&
116 ctx->Polygon.BackMode == mode)
117 return;
118 FLUSH_VERTICES(ctx, _NEW_POLYGON);
119 ctx->Polygon.FrontMode = mode;
120 ctx->Polygon.BackMode = mode;
121 break;
122 case GL_BACK:
123 if (ctx->Polygon.BackMode == mode)
124 return;
125 FLUSH_VERTICES(ctx, _NEW_POLYGON);
126 ctx->Polygon.BackMode = mode;
127 break;
128 default:
129 _mesa_error( ctx, GL_INVALID_ENUM, "glPolygonMode(face)" );
130 return;
131 }
132
133 ctx->_TriangleCaps &= ~DD_TRI_UNFILLED;
134 if (ctx->Polygon.FrontMode!=GL_FILL || ctx->Polygon.BackMode!=GL_FILL)
135 ctx->_TriangleCaps |= DD_TRI_UNFILLED;
136
137 if (ctx->Driver.PolygonMode) {
138 (*ctx->Driver.PolygonMode)( ctx, face, mode );
139 }
140 }
141
142
143
144 void
145 _mesa_PolygonStipple( const GLubyte *pattern )
146 {
147 GET_CURRENT_CONTEXT(ctx);
148 ASSERT_OUTSIDE_BEGIN_END(ctx);
149
150 if (MESA_VERBOSE&VERBOSE_API)
151 _mesa_debug(ctx, "glPolygonStipple\n");
152
153 FLUSH_VERTICES(ctx, _NEW_POLYGONSTIPPLE);
154 _mesa_unpack_polygon_stipple(pattern, ctx->PolygonStipple, &ctx->Unpack);
155
156 if (ctx->Driver.PolygonStipple)
157 ctx->Driver.PolygonStipple( ctx, (const GLubyte *) ctx->PolygonStipple );
158 }
159
160
161
162 void
163 _mesa_GetPolygonStipple( GLubyte *dest )
164 {
165 GET_CURRENT_CONTEXT(ctx);
166 ASSERT_OUTSIDE_BEGIN_END(ctx);
167
168 if (MESA_VERBOSE&VERBOSE_API)
169 _mesa_debug(ctx, "glGetPolygonStipple\n");
170
171 _mesa_pack_polygon_stipple(ctx->PolygonStipple, dest, &ctx->Pack);
172 }
173
174
175
176 void
177 _mesa_PolygonOffset( GLfloat factor, GLfloat units )
178 {
179 GET_CURRENT_CONTEXT(ctx);
180 ASSERT_OUTSIDE_BEGIN_END(ctx);
181
182 if (MESA_VERBOSE&VERBOSE_API)
183 _mesa_debug(ctx, "glPolygonOffset %f %f\n", factor, units);
184
185 if (ctx->Polygon.OffsetFactor == factor &&
186 ctx->Polygon.OffsetUnits == units)
187 return;
188
189 FLUSH_VERTICES(ctx, _NEW_POLYGON);
190 ctx->Polygon.OffsetFactor = factor;
191 ctx->Polygon.OffsetUnits = units;
192
193 if (ctx->Driver.PolygonOffset)
194 ctx->Driver.PolygonOffset( ctx, factor, units );
195 }
196
197
198
199 void
200 _mesa_PolygonOffsetEXT( GLfloat factor, GLfloat bias )
201 {
202 GET_CURRENT_CONTEXT(ctx);
203 _mesa_PolygonOffset(factor, bias * ctx->DepthMaxF );
204 }