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
 * \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
 
31
#include "glheader.h"
32
#include "imports.h"
33
#include "bufferobj.h"
34
#include "context.h"
35
#include "image.h"
36
#include "enums.h"
37
#include "pack.h"
38
#include "polygon.h"
39
#include "mtypes.h"
40
 
41
 
42
/**
43
 * Specify whether to cull front- or back-facing facets.
44
 *
45
 * \param mode culling mode.
46
 *
47
 * \sa glCullFace().
48
 *
49
 * Verifies the parameter and updates gl_polygon_attrib::CullFaceMode. On
50
 * change, flushes the vertices and notifies the driver via
51
 * the dd_function_table::CullFace callback.
52
 */
53
void GLAPIENTRY
54
_mesa_CullFace( GLenum mode )
55
{
56
   GET_CURRENT_CONTEXT(ctx);
57
   ASSERT_OUTSIDE_BEGIN_END(ctx);
58
 
59
   if (MESA_VERBOSE&VERBOSE_API)
60
      _mesa_debug(ctx, "glCullFace %s\n", _mesa_lookup_enum_by_nr(mode));
61
 
62
   if (mode!=GL_FRONT && mode!=GL_BACK && mode!=GL_FRONT_AND_BACK) {
63
      _mesa_error( ctx, GL_INVALID_ENUM, "glCullFace" );
64
      return;
65
   }
66
 
67
   if (ctx->Polygon.CullFaceMode == mode)
68
      return;
69
 
70
   FLUSH_VERTICES(ctx, _NEW_POLYGON);
71
   ctx->Polygon.CullFaceMode = mode;
72
 
73
   if (ctx->Driver.CullFace)
74
      ctx->Driver.CullFace( ctx, mode );
75
}
76
 
77
 
78
/**
79
 * Define front- and back-facing
80
 *
81
 * \param mode orientation of front-facing polygons.
82
 *
83
 * \sa glFrontFace().
84
 *
85
 * Verifies the parameter and updates gl_polygon_attrib::FrontFace. On change
86
 * flushes the vertices and notifies the driver via
87
 * the dd_function_table::FrontFace callback.
88
 */
89
void GLAPIENTRY
90
_mesa_FrontFace( GLenum mode )
91
{
92
   GET_CURRENT_CONTEXT(ctx);
93
   ASSERT_OUTSIDE_BEGIN_END(ctx);
94
 
95
   if (MESA_VERBOSE&VERBOSE_API)
96
      _mesa_debug(ctx, "glFrontFace %s\n", _mesa_lookup_enum_by_nr(mode));
97
 
98
   if (mode!=GL_CW && mode!=GL_CCW) {
99
      _mesa_error( ctx, GL_INVALID_ENUM, "glFrontFace" );
100
      return;
101
   }
102
 
103
   if (ctx->Polygon.FrontFace == mode)
104
      return;
105
 
106
   FLUSH_VERTICES(ctx, _NEW_POLYGON);
107
   ctx->Polygon.FrontFace = mode;
108
 
109
   ctx->Polygon._FrontBit = (GLboolean) (mode == GL_CW);
110
 
111
   if (ctx->Driver.FrontFace)
112
      ctx->Driver.FrontFace( ctx, mode );
113
}
114
 
115
 
116
/**
117
 * Set the polygon rasterization mode.
118
 *
119
 * \param face the polygons which \p mode applies to.
120
 * \param mode how polygons should be rasterized.
121
 *
122
 * \sa glPolygonMode().
123
 *
124
 * Verifies the parameters and updates gl_polygon_attrib::FrontMode and
125
 * gl_polygon_attrib::BackMode. On change flushes the vertices and notifies the
126
 * driver via the dd_function_table::PolygonMode callback.
127
 */
128
void GLAPIENTRY
129
_mesa_PolygonMode( GLenum face, GLenum mode )
130
{
131
   GET_CURRENT_CONTEXT(ctx);
132
   ASSERT_OUTSIDE_BEGIN_END(ctx);
133
 
134
   if (MESA_VERBOSE&VERBOSE_API)
135
      _mesa_debug(ctx, "glPolygonMode %s %s\n",
136
                  _mesa_lookup_enum_by_nr(face),
137
                  _mesa_lookup_enum_by_nr(mode));
138
 
139
   if (mode!=GL_POINT && mode!=GL_LINE && mode!=GL_FILL) {
140
      _mesa_error( ctx, GL_INVALID_ENUM, "glPolygonMode(mode)" );
141
      return;
142
   }
143
 
144
   switch (face) {
145
   case GL_FRONT:
146
      if (ctx->Polygon.FrontMode == mode)
147
	 return;
148
      FLUSH_VERTICES(ctx, _NEW_POLYGON);
149
      ctx->Polygon.FrontMode = mode;
150
      break;
151
   case GL_FRONT_AND_BACK:
152
      if (ctx->Polygon.FrontMode == mode &&
153
	  ctx->Polygon.BackMode == mode)
154
	 return;
155
      FLUSH_VERTICES(ctx, _NEW_POLYGON);
156
      ctx->Polygon.FrontMode = mode;
157
      ctx->Polygon.BackMode = mode;
158
      break;
159
   case GL_BACK:
160
      if (ctx->Polygon.BackMode == mode)
161
	 return;
162
      FLUSH_VERTICES(ctx, _NEW_POLYGON);
163
      ctx->Polygon.BackMode = mode;
164
      break;
165
   default:
166
      _mesa_error( ctx, GL_INVALID_ENUM, "glPolygonMode(face)" );
167
      return;
168
   }
169
 
170
   if (ctx->Polygon.FrontMode == GL_FILL && ctx->Polygon.BackMode == GL_FILL)
171
      ctx->_TriangleCaps &= ~DD_TRI_UNFILLED;
172
   else
173
      ctx->_TriangleCaps |= DD_TRI_UNFILLED;
174
 
175
   if (ctx->Driver.PolygonMode)
176
      ctx->Driver.PolygonMode(ctx, face, mode);
177
}
178
 
179
#if _HAVE_FULL_GL
180
 
181
 
182
/**
183
 * This routine updates the ctx->Polygon.Stipple state.
184
 * If we're getting the stipple data from a PBO, we map the buffer
185
 * in order to access the data.
186
 * In any case, we obey the current pixel unpacking parameters when fetching
187
 * the stipple data.
188
 *
189
 * In the future, this routine should be used as a fallback, called via
190
 * ctx->Driver.PolygonStipple().  We'll have to update all the DRI drivers
191
 * too.
192
 */
193
void
194
_mesa_polygon_stipple(struct gl_context *ctx, const GLubyte *pattern)
195
{
196
   pattern = _mesa_map_validate_pbo_source(ctx, 2,
197
                                           &ctx->Unpack, 32, 32, 1,
198
                                           GL_COLOR_INDEX, GL_BITMAP, pattern,
199
                                           "glPolygonStipple");
200
   if (!pattern)
201
      return;
202
 
203
   _mesa_unpack_polygon_stipple(pattern, ctx->PolygonStipple, &ctx->Unpack);
204
 
205
   _mesa_unmap_pbo_source(ctx, &ctx->Unpack);
206
}
207
 
208
 
209
/**
210
 * Called by glPolygonStipple.
211
 */
212
void GLAPIENTRY
213
_mesa_PolygonStipple( const GLubyte *pattern )
214
{
215
   GET_CURRENT_CONTEXT(ctx);
216
   ASSERT_OUTSIDE_BEGIN_END(ctx);
217
 
218
   if (MESA_VERBOSE&VERBOSE_API)
219
      _mesa_debug(ctx, "glPolygonStipple\n");
220
 
221
   FLUSH_VERTICES(ctx, _NEW_POLYGONSTIPPLE);
222
 
223
   _mesa_polygon_stipple(ctx, pattern);
224
 
225
   if (ctx->Driver.PolygonStipple)
226
      ctx->Driver.PolygonStipple(ctx, pattern);
227
}
228
 
229
 
230
/**
231
 * Called by glPolygonStipple.
232
 */
233
void GLAPIENTRY
234
_mesa_GetPolygonStipple( GLubyte *dest )
235
{
236
   GET_CURRENT_CONTEXT(ctx);
237
   ASSERT_OUTSIDE_BEGIN_END(ctx);
238
 
239
   if (MESA_VERBOSE&VERBOSE_API)
240
      _mesa_debug(ctx, "glGetPolygonStipple\n");
241
 
242
   dest = _mesa_map_validate_pbo_dest(ctx, 2,
243
                                      &ctx->Pack, 32, 32, 1,
244
                                      GL_COLOR_INDEX, GL_BITMAP, dest,
245
                                      "glGetPolygonStipple");
246
   if (!dest)
247
      return;
248
 
249
   _mesa_pack_polygon_stipple(ctx->PolygonStipple, dest, &ctx->Pack);
250
 
251
   _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
252
}
253
 
254
 
255
void GLAPIENTRY
256
_mesa_PolygonOffset( GLfloat factor, GLfloat units )
257
{
258
   GET_CURRENT_CONTEXT(ctx);
259
   ASSERT_OUTSIDE_BEGIN_END(ctx);
260
 
261
   if (MESA_VERBOSE&VERBOSE_API)
262
      _mesa_debug(ctx, "glPolygonOffset %f %f\n", factor, units);
263
 
264
   if (ctx->Polygon.OffsetFactor == factor &&
265
       ctx->Polygon.OffsetUnits == units)
266
      return;
267
 
268
   FLUSH_VERTICES(ctx, _NEW_POLYGON);
269
   ctx->Polygon.OffsetFactor = factor;
270
   ctx->Polygon.OffsetUnits = units;
271
 
272
   if (ctx->Driver.PolygonOffset)
273
      ctx->Driver.PolygonOffset( ctx, factor, units );
274
}
275
 
276
 
277
void GLAPIENTRY
278
_mesa_PolygonOffsetEXT( GLfloat factor, GLfloat bias )
279
{
280
   GET_CURRENT_CONTEXT(ctx);
281
   /* XXX mult by DepthMaxF here??? */
282
   _mesa_PolygonOffset(factor, bias * ctx->DrawBuffer->_DepthMaxF );
283
}
284
 
285
#endif
286
 
287
 
288
/**********************************************************************/
289
/** \name Initialization */
290
/*@{*/
291
 
292
/**
293
 * Initialize the context polygon state.
294
 *
295
 * \param ctx GL context.
296
 *
297
 * Initializes __struct gl_contextRec::Polygon and __struct gl_contextRec::PolygonStipple
298
 * attribute groups.
299
 */
300
void _mesa_init_polygon( struct gl_context * ctx )
301
{
302
   /* Polygon group */
303
   ctx->Polygon.CullFlag = GL_FALSE;
304
   ctx->Polygon.CullFaceMode = GL_BACK;
305
   ctx->Polygon.FrontFace = GL_CCW;
306
   ctx->Polygon._FrontBit = 0;
307
   ctx->Polygon.FrontMode = GL_FILL;
308
   ctx->Polygon.BackMode = GL_FILL;
309
   ctx->Polygon.SmoothFlag = GL_FALSE;
310
   ctx->Polygon.StippleFlag = GL_FALSE;
311
   ctx->Polygon.OffsetFactor = 0.0F;
312
   ctx->Polygon.OffsetUnits = 0.0F;
313
   ctx->Polygon.OffsetPoint = GL_FALSE;
314
   ctx->Polygon.OffsetLine = GL_FALSE;
315
   ctx->Polygon.OffsetFill = GL_FALSE;
316
 
317
 
318
   /* Polygon Stipple group */
319
   memset( ctx->PolygonStipple, 0xff, 32*sizeof(GLuint) );
320
}
321
 
322
/*@}*/