~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/extras/Mesa/src/tnl/t_imm_api.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/*
 
3
 * Mesa 3-D graphics library
 
4
 * Version:  3.5
 
5
 *
 
6
 * Copyright (C) 1999-2001  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
 * Authors:
 
26
 *    Keith Whitwell <keithw@valinux.com>
 
27
 */
 
28
 
 
29
 
 
30
 
 
31
#include "glheader.h"
 
32
#include "context.h"
 
33
#include "dlist.h"
 
34
#include "enums.h"
 
35
#include "light.h"
 
36
#include "mem.h"
 
37
#include "state.h"
 
38
#include "colormac.h"
 
39
#include "macros.h"
 
40
 
 
41
#include "t_context.h"
 
42
#include "t_imm_api.h"
 
43
#include "t_imm_elt.h"
 
44
#include "t_imm_exec.h"
 
45
#include "t_imm_dlist.h"
 
46
 
 
47
 
 
48
/* A cassette is full or flushed on a statechange.
 
49
 */
 
50
void _tnl_flush_immediate( struct immediate *IM )
 
51
{
 
52
   GLcontext *ctx = IM->backref;
 
53
 
 
54
   if (MESA_VERBOSE & VERBOSE_IMMEDIATE)
 
55
      fprintf(stderr, "_tnl_flush_immediate IM: %d compiling: %d\n",
 
56
              IM->id, ctx->CompileFlag);
 
57
 
 
58
   if (IM->FlushElt == FLUSH_ELT_EAGER) {
 
59
      _tnl_translate_array_elts( ctx, IM, IM->LastPrimitive, IM->Count );
 
60
   }
 
61
 
 
62
   /* Mark the last primitive:
 
63
    */
 
64
   IM->PrimitiveLength[IM->LastPrimitive] = IM->Count - IM->LastPrimitive;
 
65
   IM->Primitive[IM->LastPrimitive] |= PRIM_LAST;
 
66
 
 
67
   if (ctx->CompileFlag)
 
68
      _tnl_compile_cassette( ctx, IM );
 
69
   else
 
70
      _tnl_execute_cassette( ctx, IM );
 
71
}
 
72
 
 
73
 
 
74
/* Hook for ctx->Driver.FlushVertices:
 
75
 */
 
76
void _tnl_flush_vertices( GLcontext *ctx, GLuint flags )
 
77
{
 
78
   struct immediate *IM = TNL_CURRENT_IM(ctx);
 
79
 
 
80
   if (MESA_VERBOSE & VERBOSE_IMMEDIATE)
 
81
      fprintf( stderr, 
 
82
               "_tnl_flush_vertices flags %x IM(%d) %d..%d Flag[%d]: %x\n", 
 
83
               flags, IM->id, IM->Start, IM->Count, IM->Start,
 
84
               IM->Flag[IM->Start]);
 
85
 
 
86
   if (IM->Flag[IM->Start])
 
87
      if ((flags & FLUSH_UPDATE_CURRENT) || 
 
88
          IM->Count > IM->Start ||
 
89
          (IM->Flag[IM->Start] & (VERT_BEGIN|VERT_END)))
 
90
         _tnl_flush_immediate( IM );
 
91
}
 
92
 
 
93
 
 
94
 
 
95
 
 
96
void
 
97
_tnl_save_Begin( GLenum mode )
 
98
{
 
99
   GET_CURRENT_CONTEXT(ctx);
 
100
   struct immediate *IM = TNL_CURRENT_IM(ctx);
 
101
   GLuint inflags, state;
 
102
 
 
103
/*     fprintf(stderr, "%s: before: %x\n", __FUNCTION__, IM->BeginState); */
 
104
 
 
105
   if (mode > GL_POLYGON) {
 
106
      _mesa_compile_error( ctx, GL_INVALID_ENUM, "_tnl_Begin" );
 
107
      return;
 
108
   }
 
109
 
 
110
   if (ctx->NewState)
 
111
      _mesa_update_state(ctx);
 
112
 
 
113
   if (IM->Count > IMM_MAXDATA-8) {
 
114
      _tnl_flush_immediate( IM );
 
115
      IM = TNL_CURRENT_IM(ctx);
 
116
   }
 
117
 
 
118
   /* Check for and flush buffered vertices from internal operations.
 
119
    */
 
120
   if (IM->SavedBeginState) {
 
121
      _tnl_flush_immediate( IM );
 
122
      IM = TNL_CURRENT_IM(ctx);
 
123
      IM->BeginState = IM->SavedBeginState;
 
124
      IM->SavedBeginState = 0;
 
125
   }
 
126
 
 
127
   state = IM->BeginState;
 
128
   inflags = state & (VERT_BEGIN_0|VERT_BEGIN_1);
 
129
   state |= inflags << 2;       /* set error conditions */
 
130
 
 
131
   if (inflags != (VERT_BEGIN_0|VERT_BEGIN_1))
 
132
   {
 
133
      GLuint count = IM->Count;
 
134
      GLuint last = IM->LastPrimitive;
 
135
 
 
136
      state |= (VERT_BEGIN_0|VERT_BEGIN_1);
 
137
      IM->Flag[count] |= VERT_BEGIN;
 
138
      IM->Primitive[count] = mode | PRIM_BEGIN;
 
139
      IM->PrimitiveLength[IM->LastPrimitive] = count - IM->LastPrimitive;
 
140
      IM->LastPrimitive = count;
 
141
 
 
142
      /* Not quite right.  Need to use the fallback '_aa_ArrayElement'
 
143
       * when not known to be inside begin/end and arrays are
 
144
       * unlocked.  
 
145
       */
 
146
      if (IM->FlushElt == FLUSH_ELT_EAGER) {
 
147
         _tnl_translate_array_elts( ctx, IM, last, count );
 
148
      }
 
149
   }
 
150
 
 
151
   ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
 
152
   IM->BeginState = state;
 
153
 
 
154
   /* Update save_primitive now.  Don't touch ExecPrimitive as this is
 
155
    * updated in the replay of this cassette if we are in
 
156
    * COMPILE_AND_EXECUTE mode.
 
157
    */
 
158
   if (ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN)
 
159
      ctx->Driver.CurrentSavePrimitive = PRIM_INSIDE_UNKNOWN_PRIM;
 
160
   else if (ctx->Driver.CurrentSavePrimitive == PRIM_OUTSIDE_BEGIN_END)
 
161
      ctx->Driver.CurrentSavePrimitive = mode;
 
162
}
 
163
 
 
164
 
 
165
void
 
166
_tnl_Begin( GLenum mode )
 
167
{
 
168
   GET_CURRENT_CONTEXT(ctx);
 
169
   TNLcontext *tnl = TNL_CONTEXT(ctx);
 
170
   ASSERT (!ctx->CompileFlag);
 
171
 
 
172
   if (mode > GL_POLYGON) {
 
173
      _mesa_error( ctx, GL_INVALID_ENUM, "_tnl_Begin" );
 
174
      return;
 
175
   }
 
176
 
 
177
   if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) {
 
178
      _mesa_error( ctx, GL_INVALID_OPERATION, "_tnl_Begin" );
 
179
      return;
 
180
   }
 
181
 
 
182
   if (ctx->NewState)
 
183
      _mesa_update_state(ctx);
 
184
 
 
185
   {
 
186
      struct immediate *IM = TNL_CURRENT_IM(ctx);
 
187
      if (IM->Count > IMM_MAXDATA-8) {
 
188
         _tnl_flush_immediate( IM );
 
189
         IM = TNL_CURRENT_IM(ctx);
 
190
      }
 
191
   }
 
192
 
 
193
 
 
194
   {
 
195
      struct immediate *IM = TNL_CURRENT_IM(ctx);
 
196
      GLuint count = IM->Count;
 
197
      GLuint last = IM->LastPrimitive;
 
198
 
 
199
      if (IM->Start == IM->Count &&
 
200
          tnl->Driver.NotifyBegin &&
 
201
          tnl->Driver.NotifyBegin( ctx, mode )) {
 
202
         return;
 
203
      }
 
204
 
 
205
      assert( (IM->SavedBeginState & (VERT_BEGIN_0|VERT_BEGIN_1)) == 0 );
 
206
      assert( (IM->BeginState & (VERT_BEGIN_0|VERT_BEGIN_1)) == 0 );
 
207
 
 
208
      /* Not quite right.  Need to use the fallback '_aa_ArrayElement'
 
209
       * when not known to be inside begin/end and arrays are
 
210
       * unlocked.  
 
211
       */
 
212
      if (IM->FlushElt == FLUSH_ELT_EAGER) {
 
213
         _tnl_translate_array_elts( ctx, IM, last, count );
 
214
      }
 
215
 
 
216
      IM->Flag[count] |= VERT_BEGIN;
 
217
      IM->Primitive[count] = mode | PRIM_BEGIN;
 
218
      IM->PrimitiveLength[last] = count - last;
 
219
      IM->LastPrimitive = count;
 
220
      IM->BeginState = (VERT_BEGIN_0|VERT_BEGIN_1);
 
221
 
 
222
      ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
 
223
      ctx->Driver.CurrentExecPrimitive = mode;
 
224
   }
 
225
}
 
226
 
 
227
 
 
228
/* Function which allows operations like 'glRectf' to decompose to a
 
229
 * begin/end object and vertices without worrying about what happens
 
230
 * with display lists.
 
231
 */
 
232
GLboolean
 
233
_tnl_hard_begin( GLcontext *ctx, GLenum p )
 
234
{
 
235
/*     fprintf(stderr, "%s\n", __FUNCTION__); */
 
236
 
 
237
   if (!ctx->CompileFlag) {
 
238
      /* If not compiling, treat as a normal begin().
 
239
       */
 
240
/*        fprintf(stderr, "%s: treating as glBegin\n", __FUNCTION__); */
 
241
      glBegin( p );
 
242
      return GL_TRUE;
 
243
   }
 
244
   else {
 
245
      /* Otherwise, need to do special processing to preserve the
 
246
       * condition that these vertices will only be replayed outside
 
247
       * future begin/end objects.
 
248
       */
 
249
      struct immediate *IM = TNL_CURRENT_IM(ctx);
 
250
 
 
251
      if (ctx->NewState)
 
252
         _mesa_update_state(ctx);
 
253
 
 
254
      if (IM->Count > IMM_MAXDATA-8) {
 
255
         _tnl_flush_immediate( IM );
 
256
         IM = TNL_CURRENT_IM(ctx);
 
257
      }
 
258
 
 
259
      /* A lot depends on the degree to which the display list has
 
260
       * constrained the possible begin/end states at this point:
 
261
       */
 
262
      switch (IM->BeginState & (VERT_BEGIN_0|VERT_BEGIN_1)) {
 
263
      case VERT_BEGIN_0|VERT_BEGIN_1:
 
264
         /* This is an immediate known to be inside a begin/end object.
 
265
          */
 
266
         ASSERT(ctx->Driver.CurrentSavePrimitive <= GL_POLYGON);
 
267
         IM->BeginState |= (VERT_ERROR_1|VERT_ERROR_0);
 
268
         return GL_FALSE;
 
269
 
 
270
      case VERT_BEGIN_0:
 
271
      case VERT_BEGIN_1:
 
272
         /* This is a display-list immediate in an unknown begin/end
 
273
          * state.  Assert it is empty and convert it to a 'hard' one.
 
274
          */
 
275
         ASSERT(IM->SavedBeginState == 0);
 
276
         ASSERT(ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN);
 
277
 
 
278
         /* Push current beginstate, to be restored later.  Don't worry
 
279
          * about raising errors.
 
280
          */
 
281
         IM->SavedBeginState = IM->BeginState;
 
282
 
 
283
         /* FALLTHROUGH */
 
284
 
 
285
      case 0:
 
286
         /* Unless we have fallen through, this is an immediate known to
 
287
          * be outside begin/end objects.
 
288
          */
 
289
         ASSERT(ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN ||
 
290
                ctx->Driver.CurrentSavePrimitive == PRIM_OUTSIDE_BEGIN_END);
 
291
         ASSERT (IM->FlushElt != FLUSH_ELT_EAGER);
 
292
 
 
293
         IM->BeginState |= VERT_BEGIN_0|VERT_BEGIN_1;
 
294
         IM->Flag[IM->Count] |= VERT_BEGIN;
 
295
         IM->Primitive[IM->Count] = p | PRIM_BEGIN;
 
296
         IM->PrimitiveLength[IM->LastPrimitive] = IM->Count - IM->LastPrimitive;
 
297
         IM->LastPrimitive = IM->Count;
 
298
 
 
299
         /* This is necessary as this immediate will not be flushed in
 
300
          * _tnl_end() -- we leave it active, hoping to pick up more
 
301
          * vertices before the next state change.
 
302
          */
 
303
         ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
 
304
         return GL_TRUE;
 
305
 
 
306
      default:
 
307
         assert (0);
 
308
         return GL_TRUE;
 
309
      }
 
310
   }
 
311
}
 
312
 
 
313
 
 
314
 
 
315
 
 
316
 
 
317
 
 
318
/* Both streams now outside begin/end.
 
319
 *
 
320
 * Leave SavedBeginState untouched -- attempt to gather several
 
321
 * rects/arrays together in a single immediate struct.
 
322
 */
 
323
void
 
324
_tnl_end( GLcontext *ctx )
 
325
{
 
326
   struct immediate *IM = TNL_CURRENT_IM(ctx);
 
327
   GLuint state = IM->BeginState;
 
328
   GLuint inflags = (~state) & (VERT_BEGIN_0|VERT_BEGIN_1);
 
329
 
 
330
   /* Not the case if vertices emitted without calling glBegin first:
 
331
    */
 
332
/*   assert( ctx->Driver.NeedFlush & FLUSH_STORED_VERTICES ); */
 
333
 
 
334
 
 
335
   state |= inflags << 2;       /* errors */
 
336
 
 
337
   if (inflags != (VERT_BEGIN_0|VERT_BEGIN_1))
 
338
   {
 
339
      GLuint count = IM->Count;
 
340
      GLuint last = IM->LastPrimitive;
 
341
 
 
342
      state &= ~(VERT_BEGIN_0|VERT_BEGIN_1); /* update state */
 
343
      IM->Flag[count] |= VERT_END;
 
344
      IM->Primitive[last] |= PRIM_END;
 
345
      IM->PrimitiveLength[last] = count - last;
 
346
      IM->Primitive[count] = PRIM_OUTSIDE_BEGIN_END; /* removes PRIM_BEGIN 
 
347
                                                      * flag if length == 0
 
348
                                                      */
 
349
      IM->LastPrimitive = count;
 
350
 
 
351
      if (IM->FlushElt == FLUSH_ELT_EAGER) {
 
352
         _tnl_translate_array_elts( ctx, IM, last, count );
 
353
      }
 
354
   }
 
355
 
 
356
   IM->BeginState = state;
 
357
 
 
358
   /* Only update CurrentExecPrimitive if not compiling.  If we are in
 
359
    * COMPILE_AND_EXECUTE mode, it will be done on replay of this
 
360
    * cassette.
 
361
    */
 
362
   if (!ctx->CompileFlag) {
 
363
      if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) 
 
364
         _mesa_error( ctx, GL_INVALID_OPERATION, "_tnl_End" );
 
365
      else
 
366
         ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END;
 
367
   }
 
368
 
 
369
   /* You can set this flag to get the old 'flush_vb on glEnd()'
 
370
    * behaviour.
 
371
    */
 
372
   if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
 
373
      _tnl_flush_immediate( IM );
 
374
}
 
375
 
 
376
static void
 
377
_tnl_End(void)
 
378
{
 
379
   GET_CURRENT_CONTEXT(ctx);
 
380
   _tnl_end( ctx );
 
381
 
 
382
   /* Need to keep save primitive uptodate in COMPILE and
 
383
    * COMPILE_AND_EXEC modes, need to keep exec primitive uptodate
 
384
    * otherwise.
 
385
    */
 
386
   if (ctx->CompileFlag)
 
387
      ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END;
 
388
}
 
389
 
 
390
 
 
391
#define COLOR( IM, r, g, b, a )                 \
 
392
{                                               \
 
393
   GLuint count = IM->Count;                    \
 
394
   IM->Flag[count] |= VERT_RGBA;                \
 
395
   IM->Color[count][0] = r;                     \
 
396
   IM->Color[count][1] = g;                     \
 
397
   IM->Color[count][2] = b;                     \
 
398
   IM->Color[count][3] = a;                     \
 
399
}
 
400
 
 
401
static void
 
402
_tnl_Color3f( GLfloat red, GLfloat green, GLfloat blue )
 
403
{
 
404
   GET_IMMEDIATE;
 
405
   COLOR( IM, red, green, blue, 1.0 );
 
406
}
 
407
 
 
408
static void
 
409
_tnl_Color3ub( GLubyte red, GLubyte green, GLubyte blue )
 
410
{
 
411
   GET_IMMEDIATE;
 
412
   COLOR(IM,
 
413
         UBYTE_TO_FLOAT(red),
 
414
         UBYTE_TO_FLOAT(green),
 
415
         UBYTE_TO_FLOAT(blue),
 
416
         1.0);
 
417
}
 
418
 
 
419
static void
 
420
_tnl_Color4f( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha )
 
421
{
 
422
   GET_IMMEDIATE;
 
423
   COLOR( IM, red, green, blue, alpha );
 
424
}
 
425
 
 
426
static void
 
427
_tnl_Color4ub( GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha )
 
428
{
 
429
   GET_IMMEDIATE;
 
430
   COLOR(IM,
 
431
         UBYTE_TO_FLOAT(red),
 
432
         UBYTE_TO_FLOAT(green),
 
433
         UBYTE_TO_FLOAT(blue),
 
434
         UBYTE_TO_FLOAT(alpha));
 
435
}
 
436
 
 
437
static void
 
438
_tnl_Color3fv( const GLfloat *v )
 
439
{
 
440
   GET_IMMEDIATE;
 
441
   COLOR( IM, v[0], v[1], v[2], 1.0 );
 
442
}
 
443
 
 
444
static void
 
445
_tnl_Color3ubv( const GLubyte *v )
 
446
{
 
447
   GET_IMMEDIATE;
 
448
   COLOR(IM,
 
449
         UBYTE_TO_FLOAT(v[0]),
 
450
         UBYTE_TO_FLOAT(v[1]),
 
451
         UBYTE_TO_FLOAT(v[2]),
 
452
         1.0 );
 
453
}
 
454
 
 
455
static void
 
456
_tnl_Color4fv( const GLfloat *v )
 
457
{
 
458
   GET_IMMEDIATE;
 
459
   COLOR( IM, v[0], v[1], v[2], v[3] );
 
460
}
 
461
 
 
462
static void
 
463
_tnl_Color4ubv( const GLubyte *v)
 
464
{
 
465
   GET_IMMEDIATE;
 
466
   COLOR(IM,
 
467
         UBYTE_TO_FLOAT(v[0]),
 
468
         UBYTE_TO_FLOAT(v[1]),
 
469
         UBYTE_TO_FLOAT(v[2]),
 
470
         UBYTE_TO_FLOAT(v[3]));
 
471
}
 
472
 
 
473
 
 
474
 
 
475
 
 
476
#define SECONDARY_COLOR( IM, r, g, b )          \
 
477
{                                               \
 
478
   GLuint count = IM->Count;                    \
 
479
   IM->Flag[count] |= VERT_SPEC_RGB;            \
 
480
   IM->SecondaryColor[count][0] = r;            \
 
481
   IM->SecondaryColor[count][1] = g;            \
 
482
   IM->SecondaryColor[count][2] = b;            \
 
483
}
 
484
 
 
485
static void
 
486
_tnl_SecondaryColor3fEXT( GLfloat red, GLfloat green, GLfloat blue )
 
487
{
 
488
   GET_IMMEDIATE;
 
489
   SECONDARY_COLOR( IM, red, green, blue );
 
490
}
 
491
 
 
492
static void
 
493
_tnl_SecondaryColor3ubEXT( GLubyte red, GLubyte green, GLubyte blue )
 
494
{
 
495
   GET_IMMEDIATE;
 
496
   SECONDARY_COLOR(IM,
 
497
                   UBYTE_TO_FLOAT(red),
 
498
                   UBYTE_TO_FLOAT(green),
 
499
                   UBYTE_TO_FLOAT(blue));
 
500
}
 
501
 
 
502
static void
 
503
_tnl_SecondaryColor3fvEXT( const GLfloat *v )
 
504
{
 
505
   GET_IMMEDIATE;
 
506
   SECONDARY_COLOR( IM, v[0], v[1], v[2] );
 
507
}
 
508
 
 
509
static void
 
510
_tnl_SecondaryColor3ubvEXT( const GLubyte *v )
 
511
{
 
512
   GET_IMMEDIATE;
 
513
   SECONDARY_COLOR(IM,
 
514
                   UBYTE_TO_FLOAT(v[0]),
 
515
                   UBYTE_TO_FLOAT(v[1]),
 
516
                   UBYTE_TO_FLOAT(v[2]));
 
517
}
 
518
 
 
519
 
 
520
 
 
521
 
 
522
static void
 
523
_tnl_EdgeFlag( GLboolean flag )
 
524
{
 
525
   GLuint count;
 
526
   GET_IMMEDIATE;
 
527
   count = IM->Count;
 
528
   IM->EdgeFlag[count] = flag;
 
529
   IM->Flag[count] |= VERT_EDGE;
 
530
}
 
531
 
 
532
 
 
533
static void
 
534
_tnl_EdgeFlagv( const GLboolean *flag )
 
535
{
 
536
   GLuint count;
 
537
   GET_IMMEDIATE;
 
538
   count = IM->Count;
 
539
   IM->EdgeFlag[count] = *flag;
 
540
   IM->Flag[count] |= VERT_EDGE;
 
541
}
 
542
 
 
543
 
 
544
static void
 
545
_tnl_FogCoordfEXT( GLfloat f )
 
546
{
 
547
   GLuint count;
 
548
   GET_IMMEDIATE;
 
549
   count = IM->Count;
 
550
   IM->FogCoord[count] = f;
 
551
   IM->Flag[count] |= VERT_FOG_COORD;
 
552
}
 
553
 
 
554
static void
 
555
_tnl_FogCoordfvEXT( const GLfloat *v )
 
556
{
 
557
   GLuint count;
 
558
   GET_IMMEDIATE;
 
559
   count = IM->Count;
 
560
   IM->FogCoord[count] = v[0];
 
561
   IM->Flag[count] |= VERT_FOG_COORD;
 
562
}
 
563
 
 
564
 
 
565
static void
 
566
_tnl_Indexi( GLint c )
 
567
{
 
568
   GLuint count;
 
569
   GET_IMMEDIATE;
 
570
   count = IM->Count;
 
571
   IM->Index[count] = c;
 
572
   IM->Flag[count] |= VERT_INDEX;
 
573
}
 
574
 
 
575
 
 
576
static void
 
577
_tnl_Indexiv( const GLint *c )
 
578
{
 
579
   GLuint count;
 
580
   GET_IMMEDIATE;
 
581
   count = IM->Count;
 
582
   IM->Index[count] = *c;
 
583
   IM->Flag[count] |= VERT_INDEX;
 
584
}
 
585
 
 
586
 
 
587
#define NORMAL( x, y, z )                       \
 
588
{                                               \
 
589
   GLuint count;                                \
 
590
   GLfloat *normal;                             \
 
591
   GET_IMMEDIATE;                               \
 
592
   count = IM->Count;                           \
 
593
   IM->Flag[count] |= VERT_NORM;                \
 
594
   normal = IM->Normal[count];                  \
 
595
   ASSIGN_3V(normal, x,y,z);                    \
 
596
}
 
597
 
 
598
#if defined(USE_IEEE)
 
599
#define NORMALF( x, y, z )                                      \
 
600
{                                                               \
 
601
   GLuint count;                                                \
 
602
   fi_type *normal;                                             \
 
603
   GET_IMMEDIATE;                                               \
 
604
   count = IM->Count;                                           \
 
605
   IM->Flag[count] |= VERT_NORM;                                \
 
606
   normal = (fi_type *)IM->Normal[count];                       \
 
607
   normal[0].i = ((fi_type *)&(x))->i;                          \
 
608
   normal[1].i = ((fi_type *)&(y))->i;                          \
 
609
   normal[2].i = ((fi_type *)&(z))->i;                          \
 
610
}
 
611
#else
 
612
#define NORMALF NORMAL
 
613
#endif
 
614
 
 
615
static void
 
616
_tnl_Normal3f( GLfloat nx, GLfloat ny, GLfloat nz )
 
617
{
 
618
   NORMALF(nx, ny, nz);
 
619
}
 
620
 
 
621
 
 
622
static void
 
623
_tnl_Normal3fv( const GLfloat *v )
 
624
{
 
625
   NORMALF( v[0], v[1], v[2] );
 
626
/*     struct immediate *IM = (struct immediate *)(((GLcontext *) _glapi_Context)->swtnl_im); */
 
627
/*     IM->Flag[IM->Count] = VERT_NORM; */
 
628
}
 
629
 
 
630
 
 
631
 
 
632
#define TEXCOORD1(s)                            \
 
633
{                                               \
 
634
   GLuint count;                                \
 
635
   GLfloat *tc;                                 \
 
636
   GET_IMMEDIATE;                               \
 
637
   count = IM->Count;                           \
 
638
   IM->Flag[count] |= VERT_TEX0;                \
 
639
   tc = IM->TexCoord0[count];                   \
 
640
   ASSIGN_4V(tc,s,0,0,1);                       \
 
641
}
 
642
 
 
643
#define TEXCOORD2(s,t)                          \
 
644
{                                               \
 
645
   GLuint count;                                \
 
646
   GLfloat *tc;                                 \
 
647
   GET_IMMEDIATE;                               \
 
648
   count = IM->Count;                           \
 
649
   IM->Flag[count] |= VERT_TEX0;                \
 
650
   tc = IM->TexCoord0[count];                   \
 
651
   ASSIGN_4V(tc, s,t,0,1);                      \
 
652
}
 
653
 
 
654
#define TEXCOORD3(s,t,u)                        \
 
655
{                                               \
 
656
   GLuint count;                                \
 
657
   GLfloat *tc;                                 \
 
658
   GET_IMMEDIATE;                               \
 
659
   count = IM->Count;                           \
 
660
   IM->Flag[count] |= VERT_TEX0;                \
 
661
   IM->TexSize |= TEX_0_SIZE_3;         \
 
662
   tc = IM->TexCoord0[count];                   \
 
663
   ASSIGN_4V(tc, s,t,u,1);                      \
 
664
}
 
665
 
 
666
#define TEXCOORD4(s,t,u,v)                      \
 
667
{                                               \
 
668
   GLuint count;                                \
 
669
   GLfloat *tc;                                 \
 
670
   GET_IMMEDIATE;                               \
 
671
   count = IM->Count;                           \
 
672
   IM->Flag[count] |= VERT_TEX0;                \
 
673
   IM->TexSize |= TEX_0_SIZE_4;         \
 
674
   tc = IM->TexCoord0[count];                   \
 
675
   ASSIGN_4V(tc, s,t,u,v);                      \
 
676
}
 
677
 
 
678
#if defined(USE_IEEE)
 
679
#define TEXCOORD2F(s,t)                                 \
 
680
{                                                       \
 
681
   GLuint count;                                        \
 
682
   fi_type *tc;                                         \
 
683
   GET_IMMEDIATE;                                       \
 
684
   count = IM->Count;                                   \
 
685
   IM->Flag[count] |= VERT_TEX0;                        \
 
686
   tc = (fi_type *)IM->TexCoord0[count];                \
 
687
   tc[0].i = ((fi_type *)&(s))->i;                      \
 
688
   tc[1].i = ((fi_type *)&(t))->i;                      \
 
689
   tc[2].i = 0;                                         \
 
690
   tc[3].i = IEEE_ONE;                                  \
 
691
}
 
692
#else
 
693
#define TEXCOORD2F TEXCOORD2
 
694
#endif
 
695
 
 
696
static void
 
697
_tnl_TexCoord1f( GLfloat s )
 
698
{
 
699
   TEXCOORD1(s);
 
700
}
 
701
 
 
702
 
 
703
static void
 
704
_tnl_TexCoord2f( GLfloat s, GLfloat t )
 
705
{
 
706
   TEXCOORD2F(s,t);
 
707
}
 
708
 
 
709
 
 
710
static void
 
711
_tnl_TexCoord3f( GLfloat s, GLfloat t, GLfloat r )
 
712
{
 
713
   TEXCOORD3(s,t,r);
 
714
}
 
715
 
 
716
static void
 
717
_tnl_TexCoord4f( GLfloat s, GLfloat t, GLfloat r, GLfloat q )
 
718
{
 
719
   TEXCOORD4(s,t,r,q)
 
720
}
 
721
 
 
722
static void
 
723
_tnl_TexCoord1fv( const GLfloat *v )
 
724
{
 
725
   TEXCOORD1(v[0]);
 
726
}
 
727
 
 
728
static void
 
729
_tnl_TexCoord2fv( const GLfloat *v )
 
730
{
 
731
   TEXCOORD2F(v[0],v[1]);
 
732
}
 
733
 
 
734
static void
 
735
_tnl_TexCoord3fv( const GLfloat *v )
 
736
{
 
737
   TEXCOORD3(v[0],v[1],v[2]);
 
738
}
 
739
 
 
740
static void
 
741
_tnl_TexCoord4fv( const GLfloat *v )
 
742
{
 
743
   TEXCOORD4(v[0],v[1],v[2],v[3]);
 
744
}
 
745
 
 
746
 
 
747
 
 
748
/* KW: Run into bad problems in vertex copying if we don't fully pad
 
749
 *     the incoming vertices.
 
750
 */
 
751
#define VERTEX2(IM, x,y)                        \
 
752
{                                               \
 
753
   GLuint count = IM->Count++;                  \
 
754
   GLfloat *dest = IM->Obj[count];              \
 
755
   IM->Flag[count] |= VERT_OBJ;                 \
 
756
   ASSIGN_4V(dest, x, y, 0, 1);                 \
 
757
/*     ASSERT(IM->Flag[IM->Count]==0);           */\
 
758
   if (count == IMM_MAXDATA - 1)                \
 
759
      _tnl_flush_immediate( IM );               \
 
760
}
 
761
 
 
762
#define VERTEX3(IM,x,y,z)                       \
 
763
{                                               \
 
764
   GLuint count = IM->Count++;                  \
 
765
   GLfloat *dest = IM->Obj[count];              \
 
766
   IM->Flag[count] |= VERT_OBJ_23;              \
 
767
   ASSIGN_4V(dest, x, y, z, 1);                 \
 
768
/*     ASSERT(IM->Flag[IM->Count]==0); */               \
 
769
   if (count == IMM_MAXDATA - 1)                \
 
770
      _tnl_flush_immediate( IM );               \
 
771
}
 
772
 
 
773
#define VERTEX4(IM, x,y,z,w)                    \
 
774
{                                               \
 
775
   GLuint count = IM->Count++;                  \
 
776
   GLfloat *dest = IM->Obj[count];              \
 
777
   IM->Flag[count] |= VERT_OBJ_234;             \
 
778
   ASSIGN_4V(dest, x, y, z, w);                 \
 
779
   if (count == IMM_MAXDATA - 1)                        \
 
780
      _tnl_flush_immediate( IM );               \
 
781
}
 
782
 
 
783
#if defined(USE_IEEE)
 
784
#define VERTEX2F(IM, x, y)                              \
 
785
{                                                       \
 
786
   GLuint count = IM->Count++;                          \
 
787
   fi_type *dest = (fi_type *)IM->Obj[count];           \
 
788
   IM->Flag[count] |= VERT_OBJ;                         \
 
789
   dest[0].i = ((fi_type *)&(x))->i;                    \
 
790
   dest[1].i = ((fi_type *)&(y))->i;                    \
 
791
   dest[2].i = 0;                                       \
 
792
   dest[3].i = IEEE_ONE;                                \
 
793
/*     ASSERT(IM->Flag[IM->Count]==0); */               \
 
794
   if (count == IMM_MAXDATA - 1)                        \
 
795
      _tnl_flush_immediate( IM );                       \
 
796
}
 
797
#else
 
798
#define VERTEX2F VERTEX2
 
799
#endif
 
800
 
 
801
#if defined(USE_IEEE)
 
802
#define VERTEX3F(IM, x, y, z)                           \
 
803
{                                                       \
 
804
   GLuint count = IM->Count++;                          \
 
805
   fi_type *dest = (fi_type *)IM->Obj[count];           \
 
806
   IM->Flag[count] |= VERT_OBJ_23;                      \
 
807
   dest[0].i = ((fi_type *)&(x))->i;                    \
 
808
   dest[1].i = ((fi_type *)&(y))->i;                    \
 
809
   dest[2].i = ((fi_type *)&(z))->i;                    \
 
810
   dest[3].i = IEEE_ONE;                                \
 
811
/*     ASSERT(IM->Flag[IM->Count]==0);   */             \
 
812
   if (count == IMM_MAXDATA - 1)                        \
 
813
      _tnl_flush_immediate( IM );                       \
 
814
}
 
815
#else
 
816
#define VERTEX3F VERTEX3
 
817
#endif
 
818
 
 
819
#if defined(USE_IEEE)
 
820
#define VERTEX4F(IM, x, y, z, w)                        \
 
821
{                                                       \
 
822
   GLuint count = IM->Count++;                          \
 
823
   fi_type *dest = (fi_type *)IM->Obj[count];           \
 
824
   IM->Flag[count] |= VERT_OBJ_234;                     \
 
825
   dest[0].i = ((fi_type *)&(x))->i;                    \
 
826
   dest[1].i = ((fi_type *)&(y))->i;                    \
 
827
   dest[2].i = ((fi_type *)&(z))->i;                    \
 
828
   dest[3].i = ((fi_type *)&(w))->i;                    \
 
829
   if (count == IMM_MAXDATA - 1)                        \
 
830
      _tnl_flush_immediate( IM );                       \
 
831
}
 
832
#else
 
833
#define VERTEX4F VERTEX4
 
834
#endif
 
835
 
 
836
 
 
837
 
 
838
static void
 
839
_tnl_Vertex2f( GLfloat x, GLfloat y )
 
840
{
 
841
   GET_IMMEDIATE;
 
842
   VERTEX2F( IM, x, y );
 
843
}
 
844
 
 
845
static void
 
846
_tnl_Vertex3f( GLfloat x, GLfloat y, GLfloat z )
 
847
{
 
848
   GET_IMMEDIATE;
 
849
   VERTEX3F( IM, x, y, z );
 
850
}
 
851
static void
 
852
_tnl_Vertex4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w )
 
853
{
 
854
   GET_IMMEDIATE;
 
855
   VERTEX4F( IM, x, y, z, w );
 
856
}
 
857
 
 
858
static void
 
859
_tnl_Vertex2fv( const GLfloat *v )
 
860
{
 
861
   GET_IMMEDIATE;
 
862
   VERTEX2F( IM, v[0], v[1] );
 
863
}
 
864
 
 
865
static void
 
866
_tnl_Vertex3fv( const GLfloat *v )
 
867
{
 
868
   GET_IMMEDIATE;
 
869
   VERTEX3F( IM, v[0], v[1], v[2] );
 
870
}
 
871
 
 
872
static void
 
873
_tnl_Vertex4fv( const GLfloat *v )
 
874
{
 
875
   GET_IMMEDIATE;
 
876
   VERTEX4F( IM, v[0], v[1], v[2], v[3] );
 
877
}
 
878
 
 
879
 
 
880
 
 
881
 
 
882
/*
 
883
 * GL_ARB_multitexture
 
884
 *
 
885
 * Note: the multitexture spec says that specifying an invalid target
 
886
 * has undefined results and does not have to generate an error.  Just
 
887
 * don't crash.  We no-op on invalid targets.
 
888
 */
 
889
 
 
890
#define MAX_TARGET (GL_TEXTURE0_ARB + MAX_TEXTURE_UNITS)
 
891
 
 
892
#define MULTI_TEXCOORD1(target, s)                      \
 
893
{                                                       \
 
894
   GET_IMMEDIATE;                                       \
 
895
   GLuint texunit = target - GL_TEXTURE0_ARB;           \
 
896
   if (texunit < IM->MaxTextureUnits) {                 \
 
897
      GLuint count = IM->Count;                         \
 
898
      GLfloat *tc = IM->TexCoord[texunit][count];       \
 
899
      ASSIGN_4V(tc, s, 0.0F, 0.0F, 1.0F);               \
 
900
      IM->Flag[count] |= VERT_TEX(texunit);             \
 
901
   }                                                    \
 
902
}
 
903
 
 
904
#define MULTI_TEXCOORD2(target, s, t)                   \
 
905
{                                                       \
 
906
   GET_IMMEDIATE;                                       \
 
907
   GLuint texunit = target - GL_TEXTURE0_ARB;           \
 
908
   if (texunit < IM->MaxTextureUnits) {                 \
 
909
      GLuint count = IM->Count;                         \
 
910
      GLfloat *tc = IM->TexCoord[texunit][count];       \
 
911
      ASSIGN_4V(tc, s, t, 0.0F, 1.0F);                  \
 
912
      IM->Flag[count] |= VERT_TEX(texunit);             \
 
913
   }                                                    \
 
914
}
 
915
 
 
916
#define MULTI_TEXCOORD3(target, s, t, u)                \
 
917
{                                                       \
 
918
   GET_IMMEDIATE;                                       \
 
919
   GLuint texunit = target - GL_TEXTURE0_ARB;           \
 
920
   if (texunit < IM->MaxTextureUnits) {                 \
 
921
      GLuint count = IM->Count;                         \
 
922
      GLfloat *tc = IM->TexCoord[texunit][count];       \
 
923
      ASSIGN_4V(tc, s, t, u, 1.0F);                     \
 
924
      IM->Flag[count] |= VERT_TEX(texunit);             \
 
925
      IM->TexSize |= TEX_SIZE_3(texunit);               \
 
926
   }                                                    \
 
927
}
 
928
 
 
929
#define MULTI_TEXCOORD4(target, s, t, u, v)             \
 
930
{                                                       \
 
931
   GET_IMMEDIATE;                                       \
 
932
   GLuint texunit = target - GL_TEXTURE0_ARB;           \
 
933
   if (texunit < IM->MaxTextureUnits) {                 \
 
934
      GLuint count = IM->Count;                         \
 
935
      GLfloat *tc = IM->TexCoord[texunit][count];       \
 
936
      ASSIGN_4V(tc, s, t, u, v);                        \
 
937
      IM->Flag[count] |= VERT_TEX(texunit);             \
 
938
      IM->TexSize |= TEX_SIZE_4(texunit);               \
 
939
   }                                                    \
 
940
}
 
941
 
 
942
#if defined(USE_IEEE)
 
943
#define MULTI_TEXCOORD2F(target, s, t)                          \
 
944
{                                                               \
 
945
   GET_IMMEDIATE;                                               \
 
946
   GLuint texunit = target - GL_TEXTURE0_ARB;                   \
 
947
   if (texunit < IM->MaxTextureUnits) {                         \
 
948
      GLuint count = IM->Count;                                 \
 
949
      fi_type *tc = (fi_type *)IM->TexCoord[texunit][count];    \
 
950
      IM->Flag[count] |= VERT_TEX(texunit);                     \
 
951
      tc[0].i = ((fi_type *)&(s))->i;                           \
 
952
      tc[1].i = ((fi_type *)&(t))->i;                           \
 
953
      tc[2].i = 0;                                              \
 
954
      tc[3].i = IEEE_ONE;                                       \
 
955
   }                                                            \
 
956
}
 
957
#else
 
958
#define MULTI_TEXCOORD2F MULTI_TEXCOORD2
 
959
#endif
 
960
 
 
961
static void
 
962
_tnl_MultiTexCoord1fARB(GLenum target, GLfloat s)
 
963
{
 
964
   MULTI_TEXCOORD1( target, s );
 
965
}
 
966
 
 
967
static void
 
968
_tnl_MultiTexCoord1fvARB(GLenum target, const GLfloat *v)
 
969
{
 
970
   MULTI_TEXCOORD1( target, v[0] );
 
971
}
 
972
 
 
973
static void
 
974
_tnl_MultiTexCoord2fARB(GLenum target, GLfloat s, GLfloat t)
 
975
{
 
976
   MULTI_TEXCOORD2F( target, s, t );
 
977
}
 
978
 
 
979
static void
 
980
_tnl_MultiTexCoord2fvARB(GLenum target, const GLfloat *v)
 
981
{
 
982
   MULTI_TEXCOORD2F( target, v[0], v[1] );
 
983
}
 
984
 
 
985
static void
 
986
_tnl_MultiTexCoord3fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r)
 
987
{
 
988
   MULTI_TEXCOORD3( target, s, t, r );
 
989
}
 
990
 
 
991
static void
 
992
_tnl_MultiTexCoord3fvARB(GLenum target, const GLfloat *v)
 
993
{
 
994
   MULTI_TEXCOORD3( target, v[0], v[1], v[2] );
 
995
}
 
996
 
 
997
static void
 
998
_tnl_MultiTexCoord4fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
 
999
{
 
1000
   MULTI_TEXCOORD4( target, s, t, r, q );
 
1001
}
 
1002
 
 
1003
static void
 
1004
_tnl_MultiTexCoord4fvARB(GLenum target, const GLfloat *v)
 
1005
{
 
1006
   MULTI_TEXCOORD4( target, v[0], v[1], v[2], v[3] );
 
1007
}
 
1008
 
 
1009
 
 
1010
 
 
1011
/* KW: Because the eval values don't become 'current', fixup will flow
 
1012
 *     through these vertices, and then evaluation will write on top
 
1013
 *     of the fixup results.
 
1014
 *
 
1015
 *     Note: using Obj to hold eval coord data.
 
1016
 */
 
1017
#define EVALCOORD1(IM, x)                               \
 
1018
{                                                       \
 
1019
   GLuint count = IM->Count++;                          \
 
1020
   IM->Flag[count] |= VERT_EVAL_C1;                     \
 
1021
   ASSIGN_4V(IM->Obj[count], x, 0, 0, 1);               \
 
1022
   if (count == IMM_MAXDATA-1)                          \
 
1023
      _tnl_flush_immediate( IM );                       \
 
1024
}
 
1025
 
 
1026
#define EVALCOORD2(IM, x, y)                            \
 
1027
{                                                       \
 
1028
   GLuint count = IM->Count++;                          \
 
1029
   IM->Flag[count] |= VERT_EVAL_C2;                     \
 
1030
   ASSIGN_4V(IM->Obj[count], x, y, 0, 1);               \
 
1031
   if (count == IMM_MAXDATA-1)                          \
 
1032
      _tnl_flush_immediate( IM );                       \
 
1033
}
 
1034
 
 
1035
#define EVALPOINT1(IM, x)                               \
 
1036
{                                                       \
 
1037
   GLuint count = IM->Count++;                          \
 
1038
   IM->Flag[count] |= VERT_EVAL_P1;                     \
 
1039
   ASSIGN_4V(IM->Obj[count], x, 0, 0, 1);               \
 
1040
   if (count == IMM_MAXDATA-1)                          \
 
1041
      _tnl_flush_immediate( IM );                       \
 
1042
}
 
1043
 
 
1044
#define EVALPOINT2(IM, x, y)                            \
 
1045
{                                                       \
 
1046
   GLuint count = IM->Count++;                          \
 
1047
   IM->Flag[count] |= VERT_EVAL_P2;                     \
 
1048
   ASSIGN_4V(IM->Obj[count], x, y, 0, 1);               \
 
1049
   if (count == IMM_MAXDATA-1)                          \
 
1050
      _tnl_flush_immediate( IM );                       \
 
1051
}
 
1052
 
 
1053
static void
 
1054
_tnl_EvalCoord1f( GLfloat u )
 
1055
{
 
1056
   GET_IMMEDIATE;
 
1057
   EVALCOORD1( IM, u );
 
1058
}
 
1059
 
 
1060
static void
 
1061
_tnl_EvalCoord1fv( const GLfloat *u )
 
1062
{
 
1063
   GET_IMMEDIATE;
 
1064
   EVALCOORD1( IM, (GLfloat) *u );
 
1065
}
 
1066
 
 
1067
static void
 
1068
_tnl_EvalCoord2f( GLfloat u, GLfloat v )
 
1069
{
 
1070
   GET_IMMEDIATE;
 
1071
   EVALCOORD2( IM, u, v );
 
1072
}
 
1073
 
 
1074
static void
 
1075
_tnl_EvalCoord2fv( const GLfloat *u )
 
1076
{
 
1077
   GET_IMMEDIATE;
 
1078
   EVALCOORD2( IM, u[0], u[1] );
 
1079
}
 
1080
 
 
1081
 
 
1082
static void
 
1083
_tnl_EvalPoint1( GLint i )
 
1084
{
 
1085
   GET_IMMEDIATE;
 
1086
   EVALPOINT1( IM, (GLfloat) i );
 
1087
}
 
1088
 
 
1089
 
 
1090
static void
 
1091
_tnl_EvalPoint2( GLint i, GLint j )
 
1092
{
 
1093
   GET_IMMEDIATE;
 
1094
   EVALPOINT2( IM, (GLfloat) i, (GLfloat) j );
 
1095
}
 
1096
 
 
1097
 
 
1098
/* Need to use the default array-elt outside begin/end for strict
 
1099
 * conformance.
 
1100
 */
 
1101
#define ARRAY_ELT( IM, i )                      \
 
1102
{                                               \
 
1103
   GLuint count = IM->Count;                    \
 
1104
   IM->Elt[count] = i;                          \
 
1105
   IM->Flag[count] &= IM->ArrayEltFlags;        \
 
1106
   IM->Flag[count] |= VERT_ELT;                 \
 
1107
   IM->FlushElt = IM->ArrayEltFlush;            \
 
1108
   IM->Count += IM->ArrayEltIncr;               \
 
1109
   if (IM->Count == IMM_MAXDATA)                        \
 
1110
      _tnl_flush_immediate( IM );               \
 
1111
}
 
1112
 
 
1113
 
 
1114
static void
 
1115
_tnl_ArrayElement( GLint i )
 
1116
{
 
1117
   GET_IMMEDIATE;
 
1118
   ARRAY_ELT( IM, i );
 
1119
}
 
1120
 
 
1121
 
 
1122
/* Internal functions.  These are safe to use providing either:
 
1123
 *
 
1124
 *    - It is determined that a display list is not being compiled, or
 
1125
 *    if so that these commands won't be compiled into the list (see
 
1126
 *    t_eval.c for an example).
 
1127
 *
 
1128
 *    - _tnl_hard_begin() is used instead of _tnl_[bB]egin, and tested
 
1129
 *    for a GL_TRUE return value.  See _tnl_Rectf, below.
 
1130
 */
 
1131
void
 
1132
_tnl_eval_coord1f( GLcontext *CC, GLfloat u )
 
1133
{
 
1134
   struct immediate *i = TNL_CURRENT_IM(CC);
 
1135
   EVALCOORD1( i, u );
 
1136
}
 
1137
 
 
1138
void
 
1139
_tnl_eval_coord2f( GLcontext *CC, GLfloat u, GLfloat v )
 
1140
{
 
1141
   struct immediate *i = TNL_CURRENT_IM(CC);
 
1142
   EVALCOORD2( i, u, v );
 
1143
}
 
1144
 
 
1145
 
 
1146
 
 
1147
 
 
1148
 
 
1149
 
 
1150
/* Execute a glRectf() function.  _tnl_hard_begin() ensures the check
 
1151
 * on outside_begin_end is executed even in compiled lists.  These
 
1152
 * vertices can now participate in the same immediate as regular ones,
 
1153
 * even in most display lists.  
 
1154
 */
 
1155
static void
 
1156
_tnl_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
 
1157
{
 
1158
   GET_CURRENT_CONTEXT(ctx);
 
1159
 
 
1160
   if (_tnl_hard_begin( ctx, GL_QUADS )) {
 
1161
      glVertex2f( x1, y1 );
 
1162
      glVertex2f( x2, y1 );
 
1163
      glVertex2f( x2, y2 );
 
1164
      glVertex2f( x1, y2 );
 
1165
      glEnd();
 
1166
   }
 
1167
}
 
1168
 
 
1169
static void
 
1170
_tnl_Materialfv( GLenum face, GLenum pname, const GLfloat *params )
 
1171
{
 
1172
   GET_CURRENT_CONTEXT(ctx);
 
1173
   TNLcontext *tnl = TNL_CONTEXT(ctx);
 
1174
   struct immediate *IM = TNL_CURRENT_IM(ctx);
 
1175
   GLuint count = IM->Count;
 
1176
   struct gl_material *mat;
 
1177
   GLuint bitmask = _mesa_material_bitmask(ctx, face, pname, ~0, "Materialfv");
 
1178
 
 
1179
   if (bitmask == 0)
 
1180
      return;
 
1181
   
 
1182
   if (MESA_VERBOSE & VERBOSE_API)
 
1183
      fprintf(stderr, "_tnl_Materialfv\n");
 
1184
 
 
1185
   if (tnl->IsolateMaterials &&
 
1186
       !(IM->BeginState & VERT_BEGIN_1)) /* heuristic */
 
1187
   {
 
1188
      _tnl_flush_immediate( IM );      
 
1189
      IM = TNL_CURRENT_IM(ctx);
 
1190
      count = IM->Count;
 
1191
   }
 
1192
 
 
1193
   if (!(IM->Flag[count] & VERT_MATERIAL)) {
 
1194
      if (!IM->Material) {
 
1195
         IM->Material = (GLmaterial (*)[2]) MALLOC( sizeof(GLmaterial) *
 
1196
                                                    IMM_SIZE * 2 );
 
1197
         IM->MaterialMask = (GLuint *) MALLOC( sizeof(GLuint) * IMM_SIZE );
 
1198
         IM->MaterialMask[IM->LastMaterial] = 0;
 
1199
      }
 
1200
      else if (IM->MaterialOrMask & ~bitmask) {
 
1201
         _mesa_copy_material_pairs( IM->Material[count],
 
1202
                                    IM->Material[IM->LastMaterial],
 
1203
                                    IM->MaterialOrMask & ~bitmask );
 
1204
      }
 
1205
 
 
1206
      IM->Flag[count] |= VERT_MATERIAL;
 
1207
      IM->MaterialMask[count] = 0;
 
1208
      IM->MaterialAndMask &= IM->MaterialMask[IM->LastMaterial];
 
1209
      IM->LastMaterial = count;
 
1210
   }
 
1211
 
 
1212
   IM->MaterialOrMask |= bitmask;
 
1213
   IM->MaterialMask[count] |= bitmask;
 
1214
   mat = IM->Material[count];
 
1215
 
 
1216
   if (bitmask & FRONT_AMBIENT_BIT) {
 
1217
      COPY_4FV( mat[0].Ambient, params );
 
1218
   }
 
1219
   if (bitmask & BACK_AMBIENT_BIT) {
 
1220
      COPY_4FV( mat[1].Ambient, params );
 
1221
   }
 
1222
   if (bitmask & FRONT_DIFFUSE_BIT) {
 
1223
      COPY_4FV( mat[0].Diffuse, params );
 
1224
   }
 
1225
   if (bitmask & BACK_DIFFUSE_BIT) {
 
1226
      COPY_4FV( mat[1].Diffuse, params );
 
1227
   }
 
1228
   if (bitmask & FRONT_SPECULAR_BIT) {
 
1229
      COPY_4FV( mat[0].Specular, params );
 
1230
   }
 
1231
   if (bitmask & BACK_SPECULAR_BIT) {
 
1232
      COPY_4FV( mat[1].Specular, params );
 
1233
   }
 
1234
   if (bitmask & FRONT_EMISSION_BIT) {
 
1235
      COPY_4FV( mat[0].Emission, params );
 
1236
   }
 
1237
   if (bitmask & BACK_EMISSION_BIT) {
 
1238
      COPY_4FV( mat[1].Emission, params );
 
1239
   }
 
1240
   if (bitmask & FRONT_SHININESS_BIT) {
 
1241
      GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F );
 
1242
      mat[0].Shininess = shininess;
 
1243
   }
 
1244
   if (bitmask & BACK_SHININESS_BIT) {
 
1245
      GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F );
 
1246
      mat[1].Shininess = shininess;
 
1247
   }
 
1248
   if (bitmask & FRONT_INDEXES_BIT) {
 
1249
      mat[0].AmbientIndex = params[0];
 
1250
      mat[0].DiffuseIndex = params[1];
 
1251
      mat[0].SpecularIndex = params[2];
 
1252
   }
 
1253
   if (bitmask & BACK_INDEXES_BIT) {
 
1254
      mat[1].AmbientIndex = params[0];
 
1255
      mat[1].DiffuseIndex = params[1];
 
1256
      mat[1].SpecularIndex = params[2];
 
1257
   }
 
1258
 
 
1259
   if (tnl->IsolateMaterials && 
 
1260
       !(IM->BeginState & VERT_BEGIN_1)) /* heuristic */
 
1261
   {
 
1262
      _tnl_flush_immediate( IM );
 
1263
   }
 
1264
}
 
1265
 
 
1266
void _tnl_imm_vtxfmt_init( GLcontext *ctx )
 
1267
{
 
1268
   GLvertexformat *vfmt = &(TNL_CONTEXT(ctx)->vtxfmt);
 
1269
 
 
1270
   /* All begin/end operations are handled by this vertex format:
 
1271
    */
 
1272
   vfmt->ArrayElement = _tnl_ArrayElement;
 
1273
   vfmt->Begin = _tnl_Begin;
 
1274
   vfmt->Color3f = _tnl_Color3f;
 
1275
   vfmt->Color3fv = _tnl_Color3fv;
 
1276
   vfmt->Color3ub = _tnl_Color3ub;
 
1277
   vfmt->Color3ubv = _tnl_Color3ubv;
 
1278
   vfmt->Color4f = _tnl_Color4f;
 
1279
   vfmt->Color4fv = _tnl_Color4fv;
 
1280
   vfmt->Color4ub = _tnl_Color4ub;
 
1281
   vfmt->Color4ubv = _tnl_Color4ubv;
 
1282
   vfmt->EdgeFlag = _tnl_EdgeFlag;
 
1283
   vfmt->EdgeFlagv = _tnl_EdgeFlagv;
 
1284
   vfmt->End = _tnl_End;
 
1285
   vfmt->EvalCoord1f = _tnl_EvalCoord1f;
 
1286
   vfmt->EvalCoord1fv = _tnl_EvalCoord1fv;
 
1287
   vfmt->EvalCoord2f = _tnl_EvalCoord2f;
 
1288
   vfmt->EvalCoord2fv = _tnl_EvalCoord2fv;
 
1289
   vfmt->EvalPoint1 = _tnl_EvalPoint1;
 
1290
   vfmt->EvalPoint2 = _tnl_EvalPoint2;
 
1291
   vfmt->FogCoordfEXT = _tnl_FogCoordfEXT;
 
1292
   vfmt->FogCoordfvEXT = _tnl_FogCoordfvEXT;
 
1293
   vfmt->Indexi = _tnl_Indexi;
 
1294
   vfmt->Indexiv = _tnl_Indexiv;
 
1295
   vfmt->Materialfv = _tnl_Materialfv;
 
1296
   vfmt->MultiTexCoord1fARB = _tnl_MultiTexCoord1fARB;
 
1297
   vfmt->MultiTexCoord1fvARB = _tnl_MultiTexCoord1fvARB;
 
1298
   vfmt->MultiTexCoord2fARB = _tnl_MultiTexCoord2fARB;
 
1299
   vfmt->MultiTexCoord2fvARB = _tnl_MultiTexCoord2fvARB;
 
1300
   vfmt->MultiTexCoord3fARB = _tnl_MultiTexCoord3fARB;
 
1301
   vfmt->MultiTexCoord3fvARB = _tnl_MultiTexCoord3fvARB;
 
1302
   vfmt->MultiTexCoord4fARB = _tnl_MultiTexCoord4fARB;
 
1303
   vfmt->MultiTexCoord4fvARB = _tnl_MultiTexCoord4fvARB;
 
1304
   vfmt->Normal3f = _tnl_Normal3f;
 
1305
   vfmt->Normal3fv = _tnl_Normal3fv;
 
1306
   vfmt->SecondaryColor3fEXT = _tnl_SecondaryColor3fEXT;
 
1307
   vfmt->SecondaryColor3fvEXT = _tnl_SecondaryColor3fvEXT;
 
1308
   vfmt->SecondaryColor3ubEXT = _tnl_SecondaryColor3ubEXT;
 
1309
   vfmt->SecondaryColor3ubvEXT = _tnl_SecondaryColor3ubvEXT;
 
1310
   vfmt->TexCoord1f = _tnl_TexCoord1f;
 
1311
   vfmt->TexCoord1fv = _tnl_TexCoord1fv;
 
1312
   vfmt->TexCoord2f = _tnl_TexCoord2f;
 
1313
   vfmt->TexCoord2fv = _tnl_TexCoord2fv;
 
1314
   vfmt->TexCoord3f = _tnl_TexCoord3f;
 
1315
   vfmt->TexCoord3fv = _tnl_TexCoord3fv;
 
1316
   vfmt->TexCoord4f = _tnl_TexCoord4f;
 
1317
   vfmt->TexCoord4fv = _tnl_TexCoord4fv;
 
1318
   vfmt->Vertex2f = _tnl_Vertex2f;
 
1319
   vfmt->Vertex2fv = _tnl_Vertex2fv;
 
1320
   vfmt->Vertex3f = _tnl_Vertex3f;
 
1321
   vfmt->Vertex3fv = _tnl_Vertex3fv;
 
1322
   vfmt->Vertex4f = _tnl_Vertex4f;
 
1323
   vfmt->Vertex4fv = _tnl_Vertex4fv;
 
1324
 
 
1325
   /* Outside begin/end functions (from t_varray.c, t_eval.c, ...):
 
1326
    */
 
1327
   vfmt->Rectf = _tnl_Rectf;
 
1328
 
 
1329
   /* Just use the core function:
 
1330
    */
 
1331
   vfmt->CallList = _mesa_CallList;
 
1332
 
 
1333
   vfmt->prefer_float_colors = GL_FALSE;
 
1334
}