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