8a83ec1adba7cf47686b622488aaac916a9a1377
[mesa.git] / src / mesa / tnl / t_imm_eval.c
1 /* $Id: t_imm_eval.c,v 1.9 2001/04/30 21:08:52 keithw Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.5
6 *
7 * Copyright (C) 1999-2001 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 "colormac.h"
30 #include "context.h"
31 #include "macros.h"
32 #include "mem.h"
33 #include "mmath.h"
34 #include "mtypes.h"
35 #include "math/m_eval.h"
36
37 #include "t_context.h"
38 #include "t_imm_debug.h"
39 #include "t_imm_eval.h"
40 #include "t_imm_exec.h"
41 #include "t_imm_fixup.h"
42 #include "t_imm_alloc.h"
43
44
45 static void eval_points1( GLfloat outcoord[][4],
46 GLfloat coord[][4],
47 const GLuint *flags,
48 GLfloat du, GLfloat u1 )
49 {
50 GLuint i;
51 for (i = 0 ; !(flags[i] & VERT_END_VB) ; i++)
52 if (flags[i] & VERT_EVAL_ANY) {
53 outcoord[i][0] = coord[i][0];
54 outcoord[i][1] = coord[i][1];
55 if (flags[i] & VERT_EVAL_P1)
56 outcoord[i][0] = coord[i][0] * du + u1;
57 }
58 }
59
60 static void eval_points2( GLfloat outcoord[][4],
61 GLfloat coord[][4],
62 const GLuint *flags,
63 GLfloat du, GLfloat u1,
64 GLfloat dv, GLfloat v1 )
65 {
66 GLuint i;
67 fprintf(stderr, "%p %p\n", coord, outcoord);
68 for (i = 0 ; !(flags[i] & VERT_END_VB) ; i++) {
69 if (flags[i] & VERT_EVAL_ANY) {
70 outcoord[i][0] = coord[i][0];
71 outcoord[i][1] = coord[i][1];
72 if (flags[i] & VERT_EVAL_P2) {
73 fprintf(stderr, "point %f %f ==>", coord[i][0], coord[i][1]);
74 outcoord[i][0] = coord[i][0] * du + u1;
75 outcoord[i][1] = coord[i][1] * dv + v1;
76 fprintf(stderr, "%f %f\n", outcoord[i][0], outcoord[i][1]);
77 }
78 }
79 }
80 }
81
82 static const GLubyte dirty_flags[5] = {
83 0, /* not possible */
84 VEC_DIRTY_0,
85 VEC_DIRTY_1,
86 VEC_DIRTY_2,
87 VEC_DIRTY_3
88 };
89
90
91 static void eval1_4f( GLvector4f *dest,
92 GLfloat coord[][4],
93 const GLuint *flags,
94 GLuint dimension,
95 struct gl_1d_map *map )
96 {
97 const GLfloat u1 = map->u1;
98 const GLfloat du = map->du;
99 GLfloat (*to)[4] = dest->data;
100 GLuint i;
101
102 for (i = 0 ; !(flags[i] & VERT_END_VB) ; i++)
103 if (flags[i] & (VERT_EVAL_C1|VERT_EVAL_P1)) {
104 GLfloat u = (coord[i][0] - u1) * du;
105 ASSIGN_4V(to[i], 0,0,0,1);
106 _math_horner_bezier_curve(map->Points, to[i], u,
107 dimension, map->Order);
108 }
109
110 dest->size = MAX2(dest->size, dimension);
111 dest->flags |= dirty_flags[dimension];
112 }
113
114 static void eval1_4f_ca( struct gl_client_array *dest,
115 GLfloat coord[][4],
116 const GLuint *flags,
117 GLuint dimension,
118 struct gl_1d_map *map )
119 {
120 const GLfloat u1 = map->u1;
121 const GLfloat du = map->du;
122 GLfloat (*to)[4] = (GLfloat (*)[4])dest->Ptr;
123 GLuint i;
124
125 ASSERT(dest->Type == GL_FLOAT);
126 ASSERT(dest->StrideB == 4 * sizeof(GLfloat));
127
128 for (i = 0 ; !(flags[i] & VERT_END_VB) ; i++)
129 if (flags[i] & (VERT_EVAL_C1|VERT_EVAL_P1)) {
130 GLfloat u = (coord[i][0] - u1) * du;
131 ASSIGN_4V(to[i], 0,0,0,1);
132 _math_horner_bezier_curve(map->Points, to[i], u,
133 dimension, map->Order);
134 }
135
136 dest->Size = MAX2(dest->Size, dimension);
137 }
138
139
140 static void eval1_1ui( GLvector1ui *dest,
141 GLfloat coord[][4],
142 const GLuint *flags,
143 struct gl_1d_map *map )
144 {
145 const GLfloat u1 = map->u1;
146 const GLfloat du = map->du;
147 GLuint *to = dest->data;
148 GLuint i;
149
150 for (i = 0 ; !(flags[i] & VERT_END_VB) ; i++)
151 if (flags[i] & (VERT_EVAL_C1|VERT_EVAL_P1)) {
152 GLfloat u = (coord[i][0] - u1) * du;
153 GLfloat tmp;
154 _math_horner_bezier_curve(map->Points, &tmp, u, 1, map->Order);
155 to[i] = (GLuint) (GLint) tmp;
156 }
157
158 }
159
160 static void eval1_norm( GLvector3f *dest,
161 GLfloat coord[][4],
162 const GLuint *flags,
163 struct gl_1d_map *map )
164 {
165 const GLfloat u1 = map->u1;
166 const GLfloat du = map->du;
167 GLfloat (*to)[3] = dest->data;
168 GLuint i;
169
170 for (i = 0 ; !(flags[i] & VERT_END_VB) ; i++)
171 if (flags[i] & (VERT_EVAL_C1|VERT_EVAL_P1)) {
172 GLfloat u = (coord[i][0] - u1) * du;
173 _math_horner_bezier_curve(map->Points, to[i], u, 3, map->Order);
174 }
175 }
176
177
178
179
180
181 static void eval2_obj_norm( GLvector4f *obj_ptr,
182 GLvector3f *norm_ptr,
183 GLfloat coord[][4],
184 GLuint *flags,
185 GLuint dimension,
186 struct gl_2d_map *map )
187 {
188 const GLfloat u1 = map->u1;
189 const GLfloat du = map->du;
190 const GLfloat v1 = map->v1;
191 const GLfloat dv = map->dv;
192 GLfloat (*obj)[4] = obj_ptr->data;
193 GLfloat (*normal)[3] = norm_ptr->data;
194 GLuint i;
195
196 fprintf(stderr, "%s\n", __FUNCTION__);
197
198 for (i = 0 ; !(flags[i] & VERT_END_VB) ; i++)
199 if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) {
200 GLfloat u = (coord[i][0] - u1) * du;
201 GLfloat v = (coord[i][1] - v1) * dv;
202 GLfloat du[4], dv[4];
203
204 ASSIGN_4V(obj[i], 0,0,0,1);
205 _math_de_casteljau_surf(map->Points, obj[i], du, dv, u, v, dimension,
206 map->Uorder, map->Vorder);
207
208 CROSS3(normal[i], du, dv);
209 NORMALIZE_3FV(normal[i]);
210 }
211
212 obj_ptr->size = MAX2(obj_ptr->size, dimension);
213 obj_ptr->flags |= dirty_flags[dimension];
214 }
215
216
217 static void eval2_4f( GLvector4f *dest,
218 GLfloat coord[][4],
219 const GLuint *flags,
220 GLuint dimension,
221 struct gl_2d_map *map )
222 {
223 const GLfloat u1 = map->u1;
224 const GLfloat du = map->du;
225 const GLfloat v1 = map->v1;
226 const GLfloat dv = map->dv;
227 GLfloat (*to)[4] = dest->data;
228 GLuint i;
229
230 for (i = 0 ; !(flags[i] & VERT_END_VB) ; i++)
231 if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) {
232 GLfloat u = (coord[i][0] - u1) * du;
233 GLfloat v = (coord[i][1] - v1) * dv;
234 fprintf(stderr, "coord %d: %f %f\n", i, coord[i][0], coord[i][1]);
235
236 _math_horner_bezier_surf(map->Points, to[i], u, v, dimension,
237 map->Uorder, map->Vorder);
238 }
239
240 dest->size = MAX2(dest->size, dimension);
241 dest->flags |= dirty_flags[dimension];
242 }
243
244 static void eval2_4f_ca( struct gl_client_array *dest,
245 GLfloat coord[][4],
246 const GLuint *flags,
247 GLuint dimension,
248 struct gl_2d_map *map )
249 {
250 const GLfloat u1 = map->u1;
251 const GLfloat du = map->du;
252 const GLfloat v1 = map->v1;
253 const GLfloat dv = map->dv;
254 GLfloat (*to)[4] = (GLfloat (*)[4])dest->Ptr;
255 GLuint i;
256
257 ASSERT(dest->Type == GL_FLOAT);
258 ASSERT(dest->StrideB == 4 * sizeof(GLfloat));
259
260 for (i = 0 ; !(flags[i] & VERT_END_VB) ; i++)
261 if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) {
262 GLfloat u = (coord[i][0] - u1) * du;
263 GLfloat v = (coord[i][1] - v1) * dv;
264 _math_horner_bezier_surf(map->Points, to[i], u, v, dimension,
265 map->Uorder, map->Vorder);
266 }
267
268 dest->Size = MAX2(dest->Size, dimension);
269 }
270
271
272 static void eval2_norm( GLvector3f *dest,
273 GLfloat coord[][4],
274 GLuint *flags,
275 struct gl_2d_map *map )
276 {
277 const GLfloat u1 = map->u1;
278 const GLfloat du = map->du;
279 const GLfloat v1 = map->v1;
280 const GLfloat dv = map->dv;
281 GLfloat (*to)[3] = dest->data;
282 GLuint i;
283
284 for (i = 0 ; !(flags[i] & VERT_END_VB) ; i++)
285 if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) {
286 GLfloat u = (coord[i][0] - u1) * du;
287 GLfloat v = (coord[i][1] - v1) * dv;
288 _math_horner_bezier_surf(map->Points, to[i], u, v, 3,
289 map->Uorder, map->Vorder);
290 }
291
292 }
293
294
295 static void eval2_1ui( GLvector1ui *dest,
296 GLfloat coord[][4],
297 const GLuint *flags,
298 struct gl_2d_map *map )
299 {
300 const GLfloat u1 = map->u1;
301 const GLfloat du = map->du;
302 const GLfloat v1 = map->v1;
303 const GLfloat dv = map->dv;
304 GLuint *to = dest->data;
305 GLuint i;
306
307 for (i = 0 ; !(flags[i] & VERT_END_VB) ; i++)
308 if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) {
309 GLfloat u = (coord[i][0] - u1) * du;
310 GLfloat v = (coord[i][1] - v1) * dv;
311 GLfloat tmp;
312 _math_horner_bezier_surf(map->Points, &tmp, u, v, 1,
313 map->Uorder, map->Vorder);
314
315 to[i] = (GLuint) (GLint) tmp;
316 }
317 }
318
319
320
321
322
323
324 static void copy_4f( GLfloat to[][4], GLfloat from[][4], GLuint count )
325 {
326 MEMCPY( to, from, count * sizeof(to[0]));
327 }
328
329 static void copy_4f_stride( GLfloat to[][4], GLfloat *from,
330 GLuint stride, GLuint count )
331 {
332 if (stride == 4 * sizeof(GLfloat))
333 MEMCPY( to, from, count * sizeof(to[0]));
334 else {
335 int i;
336 fprintf(stderr, "%s stride %d count %d\n", __FUNCTION__,
337 stride, count);
338 for (i = 0 ; i < count ; i++, STRIDE_F(from, stride))
339 COPY_4FV( to[i], from );
340 }
341 }
342
343 static void copy_3f( GLfloat to[][3], GLfloat from[][3], GLuint count )
344 {
345 MEMCPY( to, from, (count) * sizeof(to[0]));
346 }
347
348
349 static void copy_1ui( GLuint to[], GLuint from[], GLuint count )
350 {
351 MEMCPY( to, from, (count) * sizeof(to[0]));
352 }
353
354
355
356 /* Translate eval enabled flags to VERT_* flags.
357 */
358 static void update_eval( GLcontext *ctx )
359 {
360 TNLcontext *tnl = TNL_CONTEXT(ctx);
361 GLuint eval1 = 0, eval2 = 0;
362
363 if (ctx->Eval.Map1Index)
364 eval1 |= VERT_INDEX;
365
366 if (ctx->Eval.Map2Index)
367 eval2 |= VERT_INDEX;
368
369 if (ctx->Eval.Map1Color4)
370 eval1 |= VERT_RGBA;
371
372 if (ctx->Eval.Map2Color4)
373 eval2 |= VERT_RGBA;
374
375 if (ctx->Eval.Map1Normal)
376 eval1 |= VERT_NORM;
377
378 if (ctx->Eval.Map2Normal)
379 eval2 |= VERT_NORM;
380
381 if (ctx->Eval.Map1TextureCoord4 ||
382 ctx->Eval.Map1TextureCoord3 ||
383 ctx->Eval.Map1TextureCoord2 ||
384 ctx->Eval.Map1TextureCoord1)
385 eval1 |= VERT_TEX0;
386
387 if (ctx->Eval.Map2TextureCoord4 ||
388 ctx->Eval.Map2TextureCoord3 ||
389 ctx->Eval.Map2TextureCoord2 ||
390 ctx->Eval.Map2TextureCoord1)
391 eval2 |= VERT_TEX0;
392
393 if (ctx->Eval.Map1Vertex4)
394 eval1 |= VERT_OBJ_234;
395
396 if (ctx->Eval.Map1Vertex3)
397 eval1 |= VERT_OBJ_23;
398
399 if (ctx->Eval.Map2Vertex4) {
400 if (ctx->Eval.AutoNormal)
401 eval2 |= VERT_OBJ_234 | VERT_NORM;
402 else
403 eval2 |= VERT_OBJ_234;
404 }
405 else if (ctx->Eval.Map2Vertex3) {
406 if (ctx->Eval.AutoNormal)
407 eval2 |= VERT_OBJ_23 | VERT_NORM;
408 else
409 eval2 |= VERT_OBJ_23;
410 }
411
412 tnl->eval.EvalMap1Flags = eval1;
413 tnl->eval.EvalMap2Flags = eval2;
414 tnl->eval.EvalNewState = 0;
415 }
416
417
418 /* This looks a lot like a pipeline stage, but for various reasons is
419 * better handled outside the pipeline, and considered the final stage
420 * of fixing up an immediate struct for execution.
421 *
422 * Really want to cache the results of this function in display lists,
423 * at least for EvalMesh commands.
424 */
425 void _tnl_eval_immediate( GLcontext *ctx, struct immediate *IM )
426 {
427 TNLcontext *tnl = TNL_CONTEXT(ctx);
428 struct vertex_arrays *tmp = &tnl->imm_inputs;
429 struct immediate *store = tnl->eval.im;
430 GLuint *flags = IM->Flag + IM->CopyStart;
431 GLuint copycount;
432 GLuint orflag = IM->OrFlag;
433 GLuint any_eval1 = orflag & (VERT_EVAL_C1|VERT_EVAL_P1);
434 GLuint any_eval2 = orflag & (VERT_EVAL_C2|VERT_EVAL_P2);
435 GLuint req = 0;
436 GLuint purge_flags = 0;
437 GLfloat (*coord)[4] = IM->Obj + IM->CopyStart;
438
439 if (IM->AndFlag & VERT_EVAL_ANY)
440 copycount = IM->Start - IM->CopyStart; /* just copy copied vertices */
441 else
442 copycount = IM->Count - IM->CopyStart; /* copy all vertices */
443
444 fprintf(stderr, "%s copystart %d start %d count %d copycount %d\n",
445 __FUNCTION__, IM->CopyStart, IM->Start, IM->Count, copycount);
446
447 if (!store)
448 store = tnl->eval.im = _tnl_alloc_immediate( ctx );
449
450 if (tnl->eval.EvalNewState & _NEW_EVAL)
451 update_eval( ctx );
452
453 if (any_eval1) {
454 req |= tnl->pipeline.inputs & tnl->eval.EvalMap1Flags;
455
456 if (!ctx->Eval.Map1Vertex4 && !ctx->Eval.Map1Vertex3)
457 purge_flags = (VERT_EVAL_P1|VERT_EVAL_C1);
458
459 if (orflag & VERT_EVAL_P1) {
460 eval_points1( store->Obj + IM->CopyStart,
461 coord, flags,
462 ctx->Eval.MapGrid1du,
463 ctx->Eval.MapGrid1u1);
464
465 coord = store->Obj + IM->CopyStart;
466 }
467 }
468
469 if (any_eval2) {
470 req |= tnl->pipeline.inputs & tnl->eval.EvalMap2Flags;
471
472 if (!ctx->Eval.Map2Vertex4 && !ctx->Eval.Map2Vertex3)
473 purge_flags |= (VERT_EVAL_P2|VERT_EVAL_C2);
474
475 if (orflag & VERT_EVAL_P2) {
476 eval_points2( store->Obj + IM->CopyStart,
477 coord, flags,
478 ctx->Eval.MapGrid2du,
479 ctx->Eval.MapGrid2u1,
480 ctx->Eval.MapGrid2dv,
481 ctx->Eval.MapGrid2v1 );
482
483 coord = store->Obj + IM->CopyStart;
484 }
485 }
486
487
488 _tnl_print_vert_flags(__FUNCTION__, req);
489
490 /* Perform the evaluations on active data elements.
491 */
492 if (req & VERT_INDEX)
493 {
494 GLuint generated = 0;
495
496 if (copycount)
497 copy_1ui( store->Index + IM->CopyStart, tmp->Index.data, copycount );
498
499 tmp->Index.data = store->Index + IM->CopyStart;
500 tmp->Index.start = store->Index + IM->CopyStart;
501
502 if (ctx->Eval.Map1Index && any_eval1) {
503 eval1_1ui( &tmp->Index, coord, flags, &ctx->EvalMap.Map1Index );
504 generated |= VERT_EVAL_C1|VERT_EVAL_P1;
505 }
506
507 if (ctx->Eval.Map2Index && any_eval2) {
508 eval2_1ui( &tmp->Index, coord, flags, &ctx->EvalMap.Map2Index );
509 generated |= VERT_EVAL_C2|VERT_EVAL_P2;
510 }
511
512 /* Propogate values to generate correct vertices when vertex
513 * maps are disabled.
514 */
515 if (purge_flags & generated)
516 _tnl_fixup_1ui( tmp->Index.data, flags, 0,
517 VERT_INDEX|
518 VERT_OBJ|
519 generated|
520 (VERT_EVAL_ANY&~purge_flags) );
521 }
522
523 if (req & VERT_RGBA)
524 {
525 GLuint generated = 0;
526
527 if (copycount)
528 copy_4f_stride( store->Color + IM->CopyStart,
529 (GLfloat *)tmp->Color.Ptr,
530 tmp->Color.StrideB,
531 copycount );
532
533 tmp->Color.Ptr = store->Color + IM->CopyStart;
534 tmp->Color.StrideB = 4 * sizeof(GLfloat);
535 tmp->Color.Flags = 0;
536 tnl->vb.importable_data &= ~VERT_RGBA;
537
538 if (ctx->Eval.Map1Color4 && any_eval1) {
539 eval1_4f_ca( &tmp->Color, coord, flags, 4, &ctx->EvalMap.Map1Color4 );
540 generated |= VERT_EVAL_C1|VERT_EVAL_P1;
541 }
542
543 if (ctx->Eval.Map2Color4 && any_eval2) {
544 eval2_4f_ca( &tmp->Color, coord, flags, 4, &ctx->EvalMap.Map2Color4 );
545 generated |= VERT_EVAL_C2|VERT_EVAL_P2;
546 }
547
548 /* Propogate values to generate correct vertices when vertex
549 * maps are disabled.
550 */
551 if (purge_flags & generated)
552 _tnl_fixup_4f( store->Color + IM->CopyStart,
553 flags, 0,
554 VERT_RGBA|
555 VERT_OBJ|
556 generated|
557 (VERT_EVAL_ANY&~purge_flags) );
558 }
559
560
561 if (req & VERT_TEX(0))
562 {
563 GLuint generated = 0;
564
565 if (copycount)
566 copy_4f( store->TexCoord[0] + IM->CopyStart,
567 tmp->TexCoord[0].data, copycount );
568 else
569 tmp->TexCoord[0].size = 0;
570
571 tmp->TexCoord[0].data = store->TexCoord[0] + IM->CopyStart;
572 tmp->TexCoord[0].start = (GLfloat *)tmp->TexCoord[0].data;
573
574 if (any_eval1) {
575 if (ctx->Eval.Map1TextureCoord4) {
576 eval1_4f( &tmp->TexCoord[0], coord, flags, 4,
577 &ctx->EvalMap.Map1Texture4 );
578 generated |= VERT_EVAL_C1|VERT_EVAL_P1;
579 }
580 else if (ctx->Eval.Map1TextureCoord3) {
581 eval1_4f( &tmp->TexCoord[0], coord, flags, 3,
582 &ctx->EvalMap.Map1Texture3 );
583 generated |= VERT_EVAL_C1|VERT_EVAL_P1;
584 }
585 else if (ctx->Eval.Map1TextureCoord2) {
586 eval1_4f( &tmp->TexCoord[0], coord, flags, 2,
587 &ctx->EvalMap.Map1Texture2 );
588 generated |= VERT_EVAL_C1|VERT_EVAL_P1;
589 }
590 else if (ctx->Eval.Map1TextureCoord1) {
591 eval1_4f( &tmp->TexCoord[0], coord, flags, 1,
592 &ctx->EvalMap.Map1Texture1 );
593 generated |= VERT_EVAL_C1|VERT_EVAL_P1;
594 }
595 }
596
597 if (any_eval2) {
598 if (ctx->Eval.Map2TextureCoord4) {
599 eval2_4f( &tmp->TexCoord[0], coord, flags, 4,
600 &ctx->EvalMap.Map2Texture4 );
601 generated |= VERT_EVAL_C2|VERT_EVAL_P2;
602 }
603 else if (ctx->Eval.Map2TextureCoord3) {
604 eval2_4f( &tmp->TexCoord[0], coord, flags, 3,
605 &ctx->EvalMap.Map2Texture3 );
606 generated |= VERT_EVAL_C2|VERT_EVAL_P2;
607 }
608 else if (ctx->Eval.Map2TextureCoord2) {
609 eval2_4f( &tmp->TexCoord[0], coord, flags, 2,
610 &ctx->EvalMap.Map2Texture2 );
611 generated |= VERT_EVAL_C2|VERT_EVAL_P2;
612 }
613 else if (ctx->Eval.Map2TextureCoord1) {
614 eval2_4f( &tmp->TexCoord[0], coord, flags, 1,
615 &ctx->EvalMap.Map2Texture1 );
616 generated |= VERT_EVAL_C2|VERT_EVAL_P2;
617 }
618 }
619
620 /* Propogate values to generate correct vertices when vertex
621 * maps are disabled.
622 */
623 if (purge_flags & generated)
624 _tnl_fixup_4f( tmp->TexCoord[0].data, flags, 0,
625 VERT_TEX0|
626 VERT_OBJ|
627 generated|
628 (VERT_EVAL_ANY&~purge_flags) );
629 }
630
631
632 if (req & VERT_NORM)
633 {
634 GLuint generated = 0;
635
636 if (copycount) {
637 fprintf(stderr, "%s: Copy normals\n", __FUNCTION__);
638 copy_3f( store->Normal + IM->CopyStart, tmp->Normal.data,
639 copycount );
640 }
641
642 tmp->Normal.data = store->Normal + IM->CopyStart;
643 tmp->Normal.start = (GLfloat *)tmp->Normal.data;
644
645 if (ctx->Eval.Map1Normal && any_eval1) {
646 eval1_norm( &tmp->Normal, coord, flags,
647 &ctx->EvalMap.Map1Normal );
648 generated |= VERT_EVAL_C1|VERT_EVAL_P1;
649 }
650
651 if (ctx->Eval.Map2Normal && any_eval2) {
652 eval2_norm( &tmp->Normal, coord, flags,
653 &ctx->EvalMap.Map2Normal );
654 generated |= VERT_EVAL_C2|VERT_EVAL_P2;
655 }
656
657 /* Propogate values to generate correct vertices when vertex
658 * maps are disabled.
659 */
660 if (purge_flags & generated)
661 _tnl_fixup_3f( tmp->Normal.data, flags, 0,
662 VERT_NORM|
663 VERT_OBJ|
664 generated|
665 (VERT_EVAL_ANY&~purge_flags) );
666 }
667
668
669
670 /* In the AutoNormal case, the copy and assignment of tmp->NormalPtr
671 * are done above.
672 */
673 if (req & VERT_OBJ)
674 {
675 if (copycount) {
676 /* This copy may already have occurred when eliminating
677 * glEvalPoint calls:
678 */
679 if (coord != store->Obj + IM->CopyStart)
680 copy_4f( store->Obj + IM->CopyStart, tmp->Obj.data, copycount );
681 } else
682 tmp->Obj.size = 0;
683
684 tmp->Obj.data = store->Obj + IM->CopyStart;
685 tmp->Obj.start = (GLfloat *)tmp->Obj.data;
686
687 /* Note: Normal data is already prepared above.
688 */
689
690 if (any_eval1) {
691 if (ctx->Eval.Map1Vertex4) {
692 eval1_4f( &tmp->Obj, coord, flags, 4,
693 &ctx->EvalMap.Map1Vertex4 );
694 }
695 else if (ctx->Eval.Map1Vertex3) {
696 eval1_4f( &tmp->Obj, coord, flags, 3,
697 &ctx->EvalMap.Map1Vertex3 );
698 }
699 }
700
701 if (any_eval2) {
702 if (ctx->Eval.Map2Vertex4)
703 {
704 if (ctx->Eval.AutoNormal && (req & VERT_NORM))
705 eval2_obj_norm( &tmp->Obj, &tmp->Normal, coord, flags, 4,
706 &ctx->EvalMap.Map2Vertex4 );
707 else
708 eval2_4f( &tmp->Obj, coord, flags, 4,
709 &ctx->EvalMap.Map2Vertex4 );
710 }
711 else if (ctx->Eval.Map2Vertex3)
712 {
713 if (ctx->Eval.AutoNormal && (req & VERT_NORM))
714 eval2_obj_norm( &tmp->Obj, &tmp->Normal, coord, flags, 3,
715 &ctx->EvalMap.Map2Vertex3 );
716 else
717 eval2_4f( &tmp->Obj, coord, flags, 3,
718 &ctx->EvalMap.Map2Vertex3 );
719 }
720 }
721 }
722
723
724 /* Calculate new IM->Elts, IM->Primitive, IM->PrimitiveLength for
725 * the case where vertex maps are not enabled for some received eval
726 * coordinates.
727 */
728 if (purge_flags) {
729 GLuint vertex = VERT_OBJ|(VERT_EVAL_ANY & ~purge_flags);
730 GLuint last_new_prim = 0;
731 GLuint new_prim_length = 0;
732 GLuint next_old_prim = 0;
733 struct vertex_buffer *VB = &tnl->vb;
734 GLuint i,j,count = VB->Count;
735
736 fprintf(stderr, "PURGING\n");
737
738 for (i = 0, j = 0 ; i < count ; i++) {
739 if (flags[i] & vertex) {
740 store->Elt[j++] = i;
741 new_prim_length++;
742 }
743 if (i == next_old_prim) {
744 next_old_prim += VB->PrimitiveLength[i];
745 VB->PrimitiveLength[last_new_prim] = new_prim_length;
746 VB->Primitive[j] = VB->Primitive[i];
747 last_new_prim = j;
748 }
749 }
750
751 VB->Elts = store->Elt;
752 _tnl_get_purged_copy_verts( ctx, store );
753 }
754
755 /* Produce new flags array:
756 */
757 {
758 GLuint i, count = tnl->vb.Count;
759 copy_1ui( store->Flag, flags, count );
760 tnl->vb.Flag = store->Flag;
761 for (i = 0 ; i < count ; i++)
762 store->Flag[i] |= req;
763 IM->CopyOrFlag |= req; /* hack for copying. */
764 }
765 }