e946dfd1bfa01e6701524f0c5024c0fa3825a04e
1 /* $Id: t_imm_eval.c,v 1.10 2001/05/01 13:18:03 keithw Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
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:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
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.
35 #include "math/m_eval.h"
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"
45 static void eval_points1( GLfloat outcoord
[][4],
48 GLfloat du
, GLfloat u1
)
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
;
60 static void eval_points2( GLfloat outcoord
[][4],
63 GLfloat du
, GLfloat u1
,
64 GLfloat dv
, GLfloat v1
)
67 for (i
= 0 ; !(flags
[i
] & VERT_END_VB
) ; i
++) {
68 if (flags
[i
] & VERT_EVAL_ANY
) {
69 outcoord
[i
][0] = coord
[i
][0];
70 outcoord
[i
][1] = coord
[i
][1];
71 if (flags
[i
] & VERT_EVAL_P2
) {
72 outcoord
[i
][0] = coord
[i
][0] * du
+ u1
;
73 outcoord
[i
][1] = coord
[i
][1] * dv
+ v1
;
79 static const GLubyte dirty_flags
[5] = {
88 static void eval1_4f( GLvector4f
*dest
,
92 struct gl_1d_map
*map
)
94 const GLfloat u1
= map
->u1
;
95 const GLfloat du
= map
->du
;
96 GLfloat (*to
)[4] = dest
->data
;
99 for (i
= 0 ; !(flags
[i
] & VERT_END_VB
) ; i
++)
100 if (flags
[i
] & (VERT_EVAL_C1
|VERT_EVAL_P1
)) {
101 GLfloat u
= (coord
[i
][0] - u1
) * du
;
102 ASSIGN_4V(to
[i
], 0,0,0,1);
103 _math_horner_bezier_curve(map
->Points
, to
[i
], u
,
104 dimension
, map
->Order
);
107 dest
->size
= MAX2(dest
->size
, dimension
);
108 dest
->flags
|= dirty_flags
[dimension
];
111 static void eval1_4f_ca( struct gl_client_array
*dest
,
115 struct gl_1d_map
*map
)
117 const GLfloat u1
= map
->u1
;
118 const GLfloat du
= map
->du
;
119 GLfloat (*to
)[4] = (GLfloat (*)[4])dest
->Ptr
;
122 ASSERT(dest
->Type
== GL_FLOAT
);
123 ASSERT(dest
->StrideB
== 4 * sizeof(GLfloat
));
125 for (i
= 0 ; !(flags
[i
] & VERT_END_VB
) ; i
++)
126 if (flags
[i
] & (VERT_EVAL_C1
|VERT_EVAL_P1
)) {
127 GLfloat u
= (coord
[i
][0] - u1
) * du
;
128 ASSIGN_4V(to
[i
], 0,0,0,1);
129 _math_horner_bezier_curve(map
->Points
, to
[i
], u
,
130 dimension
, map
->Order
);
133 dest
->Size
= MAX2(dest
->Size
, dimension
);
137 static void eval1_1ui( GLvector1ui
*dest
,
140 struct gl_1d_map
*map
)
142 const GLfloat u1
= map
->u1
;
143 const GLfloat du
= map
->du
;
144 GLuint
*to
= dest
->data
;
147 for (i
= 0 ; !(flags
[i
] & VERT_END_VB
) ; i
++)
148 if (flags
[i
] & (VERT_EVAL_C1
|VERT_EVAL_P1
)) {
149 GLfloat u
= (coord
[i
][0] - u1
) * du
;
151 _math_horner_bezier_curve(map
->Points
, &tmp
, u
, 1, map
->Order
);
152 to
[i
] = (GLuint
) (GLint
) tmp
;
157 static void eval1_norm( GLvector3f
*dest
,
160 struct gl_1d_map
*map
)
162 const GLfloat u1
= map
->u1
;
163 const GLfloat du
= map
->du
;
164 GLfloat (*to
)[3] = dest
->data
;
167 for (i
= 0 ; !(flags
[i
] & VERT_END_VB
) ; i
++)
168 if (flags
[i
] & (VERT_EVAL_C1
|VERT_EVAL_P1
)) {
169 GLfloat u
= (coord
[i
][0] - u1
) * du
;
170 _math_horner_bezier_curve(map
->Points
, to
[i
], u
, 3, map
->Order
);
178 static void eval2_obj_norm( GLvector4f
*obj_ptr
,
179 GLvector3f
*norm_ptr
,
183 struct gl_2d_map
*map
)
185 const GLfloat u1
= map
->u1
;
186 const GLfloat du
= map
->du
;
187 const GLfloat v1
= map
->v1
;
188 const GLfloat dv
= map
->dv
;
189 GLfloat (*obj
)[4] = obj_ptr
->data
;
190 GLfloat (*normal
)[3] = norm_ptr
->data
;
193 /* fprintf(stderr, "%s\n", __FUNCTION__); */
195 for (i
= 0 ; !(flags
[i
] & VERT_END_VB
) ; i
++)
196 if (flags
[i
] & (VERT_EVAL_C2
|VERT_EVAL_P2
)) {
197 GLfloat u
= (coord
[i
][0] - u1
) * du
;
198 GLfloat v
= (coord
[i
][1] - v1
) * dv
;
199 GLfloat du
[4], dv
[4];
201 ASSIGN_4V(obj
[i
], 0,0,0,1);
202 _math_de_casteljau_surf(map
->Points
, obj
[i
], du
, dv
, u
, v
, dimension
,
203 map
->Uorder
, map
->Vorder
);
205 CROSS3(normal
[i
], du
, dv
);
206 NORMALIZE_3FV(normal
[i
]);
209 obj_ptr
->size
= MAX2(obj_ptr
->size
, dimension
);
210 obj_ptr
->flags
|= dirty_flags
[dimension
];
214 static void eval2_4f( GLvector4f
*dest
,
218 struct gl_2d_map
*map
)
220 const GLfloat u1
= map
->u1
;
221 const GLfloat du
= map
->du
;
222 const GLfloat v1
= map
->v1
;
223 const GLfloat dv
= map
->dv
;
224 GLfloat (*to
)[4] = dest
->data
;
227 for (i
= 0 ; !(flags
[i
] & VERT_END_VB
) ; i
++)
228 if (flags
[i
] & (VERT_EVAL_C2
|VERT_EVAL_P2
)) {
229 GLfloat u
= (coord
[i
][0] - u1
) * du
;
230 GLfloat v
= (coord
[i
][1] - v1
) * dv
;
231 /* fprintf(stderr, "coord %d: %f %f\n", i, coord[i][0], coord[i][1]); */
233 _math_horner_bezier_surf(map
->Points
, to
[i
], u
, v
, dimension
,
234 map
->Uorder
, map
->Vorder
);
237 dest
->size
= MAX2(dest
->size
, dimension
);
238 dest
->flags
|= dirty_flags
[dimension
];
241 static void eval2_4f_ca( struct gl_client_array
*dest
,
245 struct gl_2d_map
*map
)
247 const GLfloat u1
= map
->u1
;
248 const GLfloat du
= map
->du
;
249 const GLfloat v1
= map
->v1
;
250 const GLfloat dv
= map
->dv
;
251 GLfloat (*to
)[4] = (GLfloat (*)[4])dest
->Ptr
;
254 ASSERT(dest
->Type
== GL_FLOAT
);
255 ASSERT(dest
->StrideB
== 4 * sizeof(GLfloat
));
257 for (i
= 0 ; !(flags
[i
] & VERT_END_VB
) ; i
++)
258 if (flags
[i
] & (VERT_EVAL_C2
|VERT_EVAL_P2
)) {
259 GLfloat u
= (coord
[i
][0] - u1
) * du
;
260 GLfloat v
= (coord
[i
][1] - v1
) * dv
;
261 _math_horner_bezier_surf(map
->Points
, to
[i
], u
, v
, dimension
,
262 map
->Uorder
, map
->Vorder
);
265 dest
->Size
= MAX2(dest
->Size
, dimension
);
269 static void eval2_norm( GLvector3f
*dest
,
272 struct gl_2d_map
*map
)
274 const GLfloat u1
= map
->u1
;
275 const GLfloat du
= map
->du
;
276 const GLfloat v1
= map
->v1
;
277 const GLfloat dv
= map
->dv
;
278 GLfloat (*to
)[3] = dest
->data
;
281 for (i
= 0 ; !(flags
[i
] & VERT_END_VB
) ; i
++)
282 if (flags
[i
] & (VERT_EVAL_C2
|VERT_EVAL_P2
)) {
283 GLfloat u
= (coord
[i
][0] - u1
) * du
;
284 GLfloat v
= (coord
[i
][1] - v1
) * dv
;
285 _math_horner_bezier_surf(map
->Points
, to
[i
], u
, v
, 3,
286 map
->Uorder
, map
->Vorder
);
292 static void eval2_1ui( GLvector1ui
*dest
,
295 struct gl_2d_map
*map
)
297 const GLfloat u1
= map
->u1
;
298 const GLfloat du
= map
->du
;
299 const GLfloat v1
= map
->v1
;
300 const GLfloat dv
= map
->dv
;
301 GLuint
*to
= dest
->data
;
304 for (i
= 0 ; !(flags
[i
] & VERT_END_VB
) ; i
++)
305 if (flags
[i
] & (VERT_EVAL_C2
|VERT_EVAL_P2
)) {
306 GLfloat u
= (coord
[i
][0] - u1
) * du
;
307 GLfloat v
= (coord
[i
][1] - v1
) * dv
;
309 _math_horner_bezier_surf(map
->Points
, &tmp
, u
, v
, 1,
310 map
->Uorder
, map
->Vorder
);
312 to
[i
] = (GLuint
) (GLint
) tmp
;
321 static void copy_4f( GLfloat to
[][4], GLfloat from
[][4], GLuint count
)
323 MEMCPY( to
, from
, count
* sizeof(to
[0]));
326 static void copy_4f_stride( GLfloat to
[][4], GLfloat
*from
,
327 GLuint stride
, GLuint count
)
329 if (stride
== 4 * sizeof(GLfloat
))
330 MEMCPY( to
, from
, count
* sizeof(to
[0]));
333 /* fprintf(stderr, "%s stride %d count %d\n", __FUNCTION__, */
334 /* stride, count); */
335 for (i
= 0 ; i
< count
; i
++, STRIDE_F(from
, stride
))
336 COPY_4FV( to
[i
], from
);
340 static void copy_3f( GLfloat to
[][3], GLfloat from
[][3], GLuint count
)
342 MEMCPY( to
, from
, (count
) * sizeof(to
[0]));
346 static void copy_1ui( GLuint to
[], GLuint from
[], GLuint count
)
348 MEMCPY( to
, from
, (count
) * sizeof(to
[0]));
353 /* Translate eval enabled flags to VERT_* flags.
355 static void update_eval( GLcontext
*ctx
)
357 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
358 GLuint eval1
= 0, eval2
= 0;
360 if (ctx
->Eval
.Map1Index
)
363 if (ctx
->Eval
.Map2Index
)
366 if (ctx
->Eval
.Map1Color4
)
369 if (ctx
->Eval
.Map2Color4
)
372 if (ctx
->Eval
.Map1Normal
)
375 if (ctx
->Eval
.Map2Normal
)
378 if (ctx
->Eval
.Map1TextureCoord4
||
379 ctx
->Eval
.Map1TextureCoord3
||
380 ctx
->Eval
.Map1TextureCoord2
||
381 ctx
->Eval
.Map1TextureCoord1
)
384 if (ctx
->Eval
.Map2TextureCoord4
||
385 ctx
->Eval
.Map2TextureCoord3
||
386 ctx
->Eval
.Map2TextureCoord2
||
387 ctx
->Eval
.Map2TextureCoord1
)
390 if (ctx
->Eval
.Map1Vertex4
)
391 eval1
|= VERT_OBJ_234
;
393 if (ctx
->Eval
.Map1Vertex3
)
394 eval1
|= VERT_OBJ_23
;
396 if (ctx
->Eval
.Map2Vertex4
) {
397 if (ctx
->Eval
.AutoNormal
)
398 eval2
|= VERT_OBJ_234
| VERT_NORM
;
400 eval2
|= VERT_OBJ_234
;
402 else if (ctx
->Eval
.Map2Vertex3
) {
403 if (ctx
->Eval
.AutoNormal
)
404 eval2
|= VERT_OBJ_23
| VERT_NORM
;
406 eval2
|= VERT_OBJ_23
;
409 tnl
->eval
.EvalMap1Flags
= eval1
;
410 tnl
->eval
.EvalMap2Flags
= eval2
;
411 tnl
->eval
.EvalNewState
= 0;
415 /* This looks a lot like a pipeline stage, but for various reasons is
416 * better handled outside the pipeline, and considered the final stage
417 * of fixing up an immediate struct for execution.
419 * Really want to cache the results of this function in display lists,
420 * at least for EvalMesh commands.
422 void _tnl_eval_immediate( GLcontext
*ctx
, struct immediate
*IM
)
424 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
425 struct vertex_arrays
*tmp
= &tnl
->imm_inputs
;
426 struct immediate
*store
= tnl
->eval
.im
;
427 GLuint
*flags
= IM
->Flag
+ IM
->CopyStart
;
429 GLuint orflag
= IM
->OrFlag
;
430 GLuint any_eval1
= orflag
& (VERT_EVAL_C1
|VERT_EVAL_P1
);
431 GLuint any_eval2
= orflag
& (VERT_EVAL_C2
|VERT_EVAL_P2
);
433 GLuint purge_flags
= 0;
434 GLfloat (*coord
)[4] = IM
->Obj
+ IM
->CopyStart
;
436 if (IM
->AndFlag
& VERT_EVAL_ANY
)
437 copycount
= IM
->Start
- IM
->CopyStart
; /* just copy copied vertices */
439 copycount
= IM
->Count
- IM
->CopyStart
; /* copy all vertices */
441 /* fprintf(stderr, "%s copystart %d start %d count %d copycount %d\n", */
442 /* __FUNCTION__, IM->CopyStart, IM->Start, IM->Count, copycount); */
445 store
= tnl
->eval
.im
= _tnl_alloc_immediate( ctx
);
447 if (tnl
->eval
.EvalNewState
& _NEW_EVAL
)
451 req
|= tnl
->pipeline
.inputs
& tnl
->eval
.EvalMap1Flags
;
453 if (!ctx
->Eval
.Map1Vertex4
&& !ctx
->Eval
.Map1Vertex3
)
454 purge_flags
= (VERT_EVAL_P1
|VERT_EVAL_C1
);
456 if (orflag
& VERT_EVAL_P1
) {
457 eval_points1( store
->Obj
+ IM
->CopyStart
,
459 ctx
->Eval
.MapGrid1du
,
460 ctx
->Eval
.MapGrid1u1
);
462 coord
= store
->Obj
+ IM
->CopyStart
;
467 req
|= tnl
->pipeline
.inputs
& tnl
->eval
.EvalMap2Flags
;
469 if (!ctx
->Eval
.Map2Vertex4
&& !ctx
->Eval
.Map2Vertex3
)
470 purge_flags
|= (VERT_EVAL_P2
|VERT_EVAL_C2
);
472 if (orflag
& VERT_EVAL_P2
) {
473 eval_points2( store
->Obj
+ IM
->CopyStart
,
475 ctx
->Eval
.MapGrid2du
,
476 ctx
->Eval
.MapGrid2u1
,
477 ctx
->Eval
.MapGrid2dv
,
478 ctx
->Eval
.MapGrid2v1
);
480 coord
= store
->Obj
+ IM
->CopyStart
;
485 /* _tnl_print_vert_flags(__FUNCTION__, req); */
487 /* Perform the evaluations on active data elements.
489 if (req
& VERT_INDEX
)
491 GLuint generated
= 0;
494 copy_1ui( store
->Index
+ IM
->CopyStart
, tmp
->Index
.data
, copycount
);
496 tmp
->Index
.data
= store
->Index
+ IM
->CopyStart
;
497 tmp
->Index
.start
= store
->Index
+ IM
->CopyStart
;
499 if (ctx
->Eval
.Map1Index
&& any_eval1
) {
500 eval1_1ui( &tmp
->Index
, coord
, flags
, &ctx
->EvalMap
.Map1Index
);
501 generated
|= VERT_EVAL_C1
|VERT_EVAL_P1
;
504 if (ctx
->Eval
.Map2Index
&& any_eval2
) {
505 eval2_1ui( &tmp
->Index
, coord
, flags
, &ctx
->EvalMap
.Map2Index
);
506 generated
|= VERT_EVAL_C2
|VERT_EVAL_P2
;
509 /* Propogate values to generate correct vertices when vertex
512 if (purge_flags
& generated
)
513 _tnl_fixup_1ui( tmp
->Index
.data
, flags
, 0,
517 (VERT_EVAL_ANY
&~purge_flags
) );
522 GLuint generated
= 0;
525 copy_4f_stride( store
->Color
+ IM
->CopyStart
,
526 (GLfloat
*)tmp
->Color
.Ptr
,
530 tmp
->Color
.Ptr
= store
->Color
+ IM
->CopyStart
;
531 tmp
->Color
.StrideB
= 4 * sizeof(GLfloat
);
532 tmp
->Color
.Flags
= 0;
533 tnl
->vb
.importable_data
&= ~VERT_RGBA
;
535 if (ctx
->Eval
.Map1Color4
&& any_eval1
) {
536 eval1_4f_ca( &tmp
->Color
, coord
, flags
, 4, &ctx
->EvalMap
.Map1Color4
);
537 generated
|= VERT_EVAL_C1
|VERT_EVAL_P1
;
540 if (ctx
->Eval
.Map2Color4
&& any_eval2
) {
541 eval2_4f_ca( &tmp
->Color
, coord
, flags
, 4, &ctx
->EvalMap
.Map2Color4
);
542 generated
|= VERT_EVAL_C2
|VERT_EVAL_P2
;
545 /* Propogate values to generate correct vertices when vertex
548 if (purge_flags
& generated
)
549 _tnl_fixup_4f( store
->Color
+ IM
->CopyStart
,
554 (VERT_EVAL_ANY
&~purge_flags
) );
558 if (req
& VERT_TEX(0))
560 GLuint generated
= 0;
563 copy_4f( store
->TexCoord
[0] + IM
->CopyStart
,
564 tmp
->TexCoord
[0].data
, copycount
);
566 tmp
->TexCoord
[0].size
= 0;
568 tmp
->TexCoord
[0].data
= store
->TexCoord
[0] + IM
->CopyStart
;
569 tmp
->TexCoord
[0].start
= (GLfloat
*)tmp
->TexCoord
[0].data
;
572 if (ctx
->Eval
.Map1TextureCoord4
) {
573 eval1_4f( &tmp
->TexCoord
[0], coord
, flags
, 4,
574 &ctx
->EvalMap
.Map1Texture4
);
575 generated
|= VERT_EVAL_C1
|VERT_EVAL_P1
;
577 else if (ctx
->Eval
.Map1TextureCoord3
) {
578 eval1_4f( &tmp
->TexCoord
[0], coord
, flags
, 3,
579 &ctx
->EvalMap
.Map1Texture3
);
580 generated
|= VERT_EVAL_C1
|VERT_EVAL_P1
;
582 else if (ctx
->Eval
.Map1TextureCoord2
) {
583 eval1_4f( &tmp
->TexCoord
[0], coord
, flags
, 2,
584 &ctx
->EvalMap
.Map1Texture2
);
585 generated
|= VERT_EVAL_C1
|VERT_EVAL_P1
;
587 else if (ctx
->Eval
.Map1TextureCoord1
) {
588 eval1_4f( &tmp
->TexCoord
[0], coord
, flags
, 1,
589 &ctx
->EvalMap
.Map1Texture1
);
590 generated
|= VERT_EVAL_C1
|VERT_EVAL_P1
;
595 if (ctx
->Eval
.Map2TextureCoord4
) {
596 eval2_4f( &tmp
->TexCoord
[0], coord
, flags
, 4,
597 &ctx
->EvalMap
.Map2Texture4
);
598 generated
|= VERT_EVAL_C2
|VERT_EVAL_P2
;
600 else if (ctx
->Eval
.Map2TextureCoord3
) {
601 eval2_4f( &tmp
->TexCoord
[0], coord
, flags
, 3,
602 &ctx
->EvalMap
.Map2Texture3
);
603 generated
|= VERT_EVAL_C2
|VERT_EVAL_P2
;
605 else if (ctx
->Eval
.Map2TextureCoord2
) {
606 eval2_4f( &tmp
->TexCoord
[0], coord
, flags
, 2,
607 &ctx
->EvalMap
.Map2Texture2
);
608 generated
|= VERT_EVAL_C2
|VERT_EVAL_P2
;
610 else if (ctx
->Eval
.Map2TextureCoord1
) {
611 eval2_4f( &tmp
->TexCoord
[0], coord
, flags
, 1,
612 &ctx
->EvalMap
.Map2Texture1
);
613 generated
|= VERT_EVAL_C2
|VERT_EVAL_P2
;
617 /* Propogate values to generate correct vertices when vertex
620 if (purge_flags
& generated
)
621 _tnl_fixup_4f( tmp
->TexCoord
[0].data
, flags
, 0,
625 (VERT_EVAL_ANY
&~purge_flags
) );
631 GLuint generated
= 0;
634 /* fprintf(stderr, "%s: Copy normals\n", __FUNCTION__); */
635 copy_3f( store
->Normal
+ IM
->CopyStart
, tmp
->Normal
.data
,
639 tmp
->Normal
.data
= store
->Normal
+ IM
->CopyStart
;
640 tmp
->Normal
.start
= (GLfloat
*)tmp
->Normal
.data
;
642 if (ctx
->Eval
.Map1Normal
&& any_eval1
) {
643 eval1_norm( &tmp
->Normal
, coord
, flags
,
644 &ctx
->EvalMap
.Map1Normal
);
645 generated
|= VERT_EVAL_C1
|VERT_EVAL_P1
;
648 if (ctx
->Eval
.Map2Normal
&& any_eval2
) {
649 eval2_norm( &tmp
->Normal
, coord
, flags
,
650 &ctx
->EvalMap
.Map2Normal
);
651 generated
|= VERT_EVAL_C2
|VERT_EVAL_P2
;
654 /* Propogate values to generate correct vertices when vertex
657 if (purge_flags
& generated
)
658 _tnl_fixup_3f( tmp
->Normal
.data
, flags
, 0,
662 (VERT_EVAL_ANY
&~purge_flags
) );
667 /* In the AutoNormal case, the copy and assignment of tmp->NormalPtr
673 /* This copy may already have occurred when eliminating
676 if (coord
!= store
->Obj
+ IM
->CopyStart
)
677 copy_4f( store
->Obj
+ IM
->CopyStart
, tmp
->Obj
.data
, copycount
);
681 tmp
->Obj
.data
= store
->Obj
+ IM
->CopyStart
;
682 tmp
->Obj
.start
= (GLfloat
*)tmp
->Obj
.data
;
684 /* Note: Normal data is already prepared above.
688 if (ctx
->Eval
.Map1Vertex4
) {
689 eval1_4f( &tmp
->Obj
, coord
, flags
, 4,
690 &ctx
->EvalMap
.Map1Vertex4
);
692 else if (ctx
->Eval
.Map1Vertex3
) {
693 eval1_4f( &tmp
->Obj
, coord
, flags
, 3,
694 &ctx
->EvalMap
.Map1Vertex3
);
699 if (ctx
->Eval
.Map2Vertex4
)
701 if (ctx
->Eval
.AutoNormal
&& (req
& VERT_NORM
))
702 eval2_obj_norm( &tmp
->Obj
, &tmp
->Normal
, coord
, flags
, 4,
703 &ctx
->EvalMap
.Map2Vertex4
);
705 eval2_4f( &tmp
->Obj
, coord
, flags
, 4,
706 &ctx
->EvalMap
.Map2Vertex4
);
708 else if (ctx
->Eval
.Map2Vertex3
)
710 if (ctx
->Eval
.AutoNormal
&& (req
& VERT_NORM
))
711 eval2_obj_norm( &tmp
->Obj
, &tmp
->Normal
, coord
, flags
, 3,
712 &ctx
->EvalMap
.Map2Vertex3
);
714 eval2_4f( &tmp
->Obj
, coord
, flags
, 3,
715 &ctx
->EvalMap
.Map2Vertex3
);
721 /* Calculate new IM->Elts, IM->Primitive, IM->PrimitiveLength for
722 * the case where vertex maps are not enabled for some received eval
726 GLuint vertex
= VERT_OBJ
|(VERT_EVAL_ANY
& ~purge_flags
);
727 GLuint last_new_prim
= 0;
728 GLuint new_prim_length
= 0;
729 GLuint next_old_prim
= 0;
730 struct vertex_buffer
*VB
= &tnl
->vb
;
731 GLuint i
,j
,count
= VB
->Count
;
733 /* fprintf(stderr, "PURGING\n"); */
735 for (i
= 0, j
= 0 ; i
< count
; i
++) {
736 if (flags
[i
] & vertex
) {
740 if (i
== next_old_prim
) {
741 next_old_prim
+= VB
->PrimitiveLength
[i
];
742 VB
->PrimitiveLength
[last_new_prim
] = new_prim_length
;
743 VB
->Primitive
[j
] = VB
->Primitive
[i
];
748 VB
->Elts
= store
->Elt
;
749 _tnl_get_purged_copy_verts( ctx
, store
);
752 /* Produce new flags array:
755 GLuint i
, count
= tnl
->vb
.Count
;
756 copy_1ui( store
->Flag
, flags
, count
);
757 tnl
->vb
.Flag
= store
->Flag
;
758 for (i
= 0 ; i
< count
; i
++)
759 store
->Flag
[i
] |= req
;
760 IM
->CopyOrFlag
|= req
; /* hack for copying. */