1 /* $Id: t_imm_eval.c,v 1.9 2001/04/30 21:08:52 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 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]);
82 static const GLubyte dirty_flags
[5] = {
91 static void eval1_4f( GLvector4f
*dest
,
95 struct gl_1d_map
*map
)
97 const GLfloat u1
= map
->u1
;
98 const GLfloat du
= map
->du
;
99 GLfloat (*to
)[4] = dest
->data
;
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
);
110 dest
->size
= MAX2(dest
->size
, dimension
);
111 dest
->flags
|= dirty_flags
[dimension
];
114 static void eval1_4f_ca( struct gl_client_array
*dest
,
118 struct gl_1d_map
*map
)
120 const GLfloat u1
= map
->u1
;
121 const GLfloat du
= map
->du
;
122 GLfloat (*to
)[4] = (GLfloat (*)[4])dest
->Ptr
;
125 ASSERT(dest
->Type
== GL_FLOAT
);
126 ASSERT(dest
->StrideB
== 4 * sizeof(GLfloat
));
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
);
136 dest
->Size
= MAX2(dest
->Size
, dimension
);
140 static void eval1_1ui( GLvector1ui
*dest
,
143 struct gl_1d_map
*map
)
145 const GLfloat u1
= map
->u1
;
146 const GLfloat du
= map
->du
;
147 GLuint
*to
= dest
->data
;
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
;
154 _math_horner_bezier_curve(map
->Points
, &tmp
, u
, 1, map
->Order
);
155 to
[i
] = (GLuint
) (GLint
) tmp
;
160 static void eval1_norm( GLvector3f
*dest
,
163 struct gl_1d_map
*map
)
165 const GLfloat u1
= map
->u1
;
166 const GLfloat du
= map
->du
;
167 GLfloat (*to
)[3] = dest
->data
;
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
);
181 static void eval2_obj_norm( GLvector4f
*obj_ptr
,
182 GLvector3f
*norm_ptr
,
186 struct gl_2d_map
*map
)
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
;
196 fprintf(stderr
, "%s\n", __FUNCTION__
);
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];
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
);
208 CROSS3(normal
[i
], du
, dv
);
209 NORMALIZE_3FV(normal
[i
]);
212 obj_ptr
->size
= MAX2(obj_ptr
->size
, dimension
);
213 obj_ptr
->flags
|= dirty_flags
[dimension
];
217 static void eval2_4f( GLvector4f
*dest
,
221 struct gl_2d_map
*map
)
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
;
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]);
236 _math_horner_bezier_surf(map
->Points
, to
[i
], u
, v
, dimension
,
237 map
->Uorder
, map
->Vorder
);
240 dest
->size
= MAX2(dest
->size
, dimension
);
241 dest
->flags
|= dirty_flags
[dimension
];
244 static void eval2_4f_ca( struct gl_client_array
*dest
,
248 struct gl_2d_map
*map
)
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
;
257 ASSERT(dest
->Type
== GL_FLOAT
);
258 ASSERT(dest
->StrideB
== 4 * sizeof(GLfloat
));
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
);
268 dest
->Size
= MAX2(dest
->Size
, dimension
);
272 static void eval2_norm( GLvector3f
*dest
,
275 struct gl_2d_map
*map
)
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
;
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
);
295 static void eval2_1ui( GLvector1ui
*dest
,
298 struct gl_2d_map
*map
)
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
;
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
;
312 _math_horner_bezier_surf(map
->Points
, &tmp
, u
, v
, 1,
313 map
->Uorder
, map
->Vorder
);
315 to
[i
] = (GLuint
) (GLint
) tmp
;
324 static void copy_4f( GLfloat to
[][4], GLfloat from
[][4], GLuint count
)
326 MEMCPY( to
, from
, count
* sizeof(to
[0]));
329 static void copy_4f_stride( GLfloat to
[][4], GLfloat
*from
,
330 GLuint stride
, GLuint count
)
332 if (stride
== 4 * sizeof(GLfloat
))
333 MEMCPY( to
, from
, count
* sizeof(to
[0]));
336 fprintf(stderr
, "%s stride %d count %d\n", __FUNCTION__
,
338 for (i
= 0 ; i
< count
; i
++, STRIDE_F(from
, stride
))
339 COPY_4FV( to
[i
], from
);
343 static void copy_3f( GLfloat to
[][3], GLfloat from
[][3], GLuint count
)
345 MEMCPY( to
, from
, (count
) * sizeof(to
[0]));
349 static void copy_1ui( GLuint to
[], GLuint from
[], GLuint count
)
351 MEMCPY( to
, from
, (count
) * sizeof(to
[0]));
356 /* Translate eval enabled flags to VERT_* flags.
358 static void update_eval( GLcontext
*ctx
)
360 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
361 GLuint eval1
= 0, eval2
= 0;
363 if (ctx
->Eval
.Map1Index
)
366 if (ctx
->Eval
.Map2Index
)
369 if (ctx
->Eval
.Map1Color4
)
372 if (ctx
->Eval
.Map2Color4
)
375 if (ctx
->Eval
.Map1Normal
)
378 if (ctx
->Eval
.Map2Normal
)
381 if (ctx
->Eval
.Map1TextureCoord4
||
382 ctx
->Eval
.Map1TextureCoord3
||
383 ctx
->Eval
.Map1TextureCoord2
||
384 ctx
->Eval
.Map1TextureCoord1
)
387 if (ctx
->Eval
.Map2TextureCoord4
||
388 ctx
->Eval
.Map2TextureCoord3
||
389 ctx
->Eval
.Map2TextureCoord2
||
390 ctx
->Eval
.Map2TextureCoord1
)
393 if (ctx
->Eval
.Map1Vertex4
)
394 eval1
|= VERT_OBJ_234
;
396 if (ctx
->Eval
.Map1Vertex3
)
397 eval1
|= VERT_OBJ_23
;
399 if (ctx
->Eval
.Map2Vertex4
) {
400 if (ctx
->Eval
.AutoNormal
)
401 eval2
|= VERT_OBJ_234
| VERT_NORM
;
403 eval2
|= VERT_OBJ_234
;
405 else if (ctx
->Eval
.Map2Vertex3
) {
406 if (ctx
->Eval
.AutoNormal
)
407 eval2
|= VERT_OBJ_23
| VERT_NORM
;
409 eval2
|= VERT_OBJ_23
;
412 tnl
->eval
.EvalMap1Flags
= eval1
;
413 tnl
->eval
.EvalMap2Flags
= eval2
;
414 tnl
->eval
.EvalNewState
= 0;
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.
422 * Really want to cache the results of this function in display lists,
423 * at least for EvalMesh commands.
425 void _tnl_eval_immediate( GLcontext
*ctx
, struct immediate
*IM
)
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
;
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
);
436 GLuint purge_flags
= 0;
437 GLfloat (*coord
)[4] = IM
->Obj
+ IM
->CopyStart
;
439 if (IM
->AndFlag
& VERT_EVAL_ANY
)
440 copycount
= IM
->Start
- IM
->CopyStart
; /* just copy copied vertices */
442 copycount
= IM
->Count
- IM
->CopyStart
; /* copy all vertices */
444 fprintf(stderr
, "%s copystart %d start %d count %d copycount %d\n",
445 __FUNCTION__
, IM
->CopyStart
, IM
->Start
, IM
->Count
, copycount
);
448 store
= tnl
->eval
.im
= _tnl_alloc_immediate( ctx
);
450 if (tnl
->eval
.EvalNewState
& _NEW_EVAL
)
454 req
|= tnl
->pipeline
.inputs
& tnl
->eval
.EvalMap1Flags
;
456 if (!ctx
->Eval
.Map1Vertex4
&& !ctx
->Eval
.Map1Vertex3
)
457 purge_flags
= (VERT_EVAL_P1
|VERT_EVAL_C1
);
459 if (orflag
& VERT_EVAL_P1
) {
460 eval_points1( store
->Obj
+ IM
->CopyStart
,
462 ctx
->Eval
.MapGrid1du
,
463 ctx
->Eval
.MapGrid1u1
);
465 coord
= store
->Obj
+ IM
->CopyStart
;
470 req
|= tnl
->pipeline
.inputs
& tnl
->eval
.EvalMap2Flags
;
472 if (!ctx
->Eval
.Map2Vertex4
&& !ctx
->Eval
.Map2Vertex3
)
473 purge_flags
|= (VERT_EVAL_P2
|VERT_EVAL_C2
);
475 if (orflag
& VERT_EVAL_P2
) {
476 eval_points2( store
->Obj
+ IM
->CopyStart
,
478 ctx
->Eval
.MapGrid2du
,
479 ctx
->Eval
.MapGrid2u1
,
480 ctx
->Eval
.MapGrid2dv
,
481 ctx
->Eval
.MapGrid2v1
);
483 coord
= store
->Obj
+ IM
->CopyStart
;
488 _tnl_print_vert_flags(__FUNCTION__
, req
);
490 /* Perform the evaluations on active data elements.
492 if (req
& VERT_INDEX
)
494 GLuint generated
= 0;
497 copy_1ui( store
->Index
+ IM
->CopyStart
, tmp
->Index
.data
, copycount
);
499 tmp
->Index
.data
= store
->Index
+ IM
->CopyStart
;
500 tmp
->Index
.start
= store
->Index
+ IM
->CopyStart
;
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
;
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
;
512 /* Propogate values to generate correct vertices when vertex
515 if (purge_flags
& generated
)
516 _tnl_fixup_1ui( tmp
->Index
.data
, flags
, 0,
520 (VERT_EVAL_ANY
&~purge_flags
) );
525 GLuint generated
= 0;
528 copy_4f_stride( store
->Color
+ IM
->CopyStart
,
529 (GLfloat
*)tmp
->Color
.Ptr
,
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
;
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
;
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
;
548 /* Propogate values to generate correct vertices when vertex
551 if (purge_flags
& generated
)
552 _tnl_fixup_4f( store
->Color
+ IM
->CopyStart
,
557 (VERT_EVAL_ANY
&~purge_flags
) );
561 if (req
& VERT_TEX(0))
563 GLuint generated
= 0;
566 copy_4f( store
->TexCoord
[0] + IM
->CopyStart
,
567 tmp
->TexCoord
[0].data
, copycount
);
569 tmp
->TexCoord
[0].size
= 0;
571 tmp
->TexCoord
[0].data
= store
->TexCoord
[0] + IM
->CopyStart
;
572 tmp
->TexCoord
[0].start
= (GLfloat
*)tmp
->TexCoord
[0].data
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
620 /* Propogate values to generate correct vertices when vertex
623 if (purge_flags
& generated
)
624 _tnl_fixup_4f( tmp
->TexCoord
[0].data
, flags
, 0,
628 (VERT_EVAL_ANY
&~purge_flags
) );
634 GLuint generated
= 0;
637 fprintf(stderr
, "%s: Copy normals\n", __FUNCTION__
);
638 copy_3f( store
->Normal
+ IM
->CopyStart
, tmp
->Normal
.data
,
642 tmp
->Normal
.data
= store
->Normal
+ IM
->CopyStart
;
643 tmp
->Normal
.start
= (GLfloat
*)tmp
->Normal
.data
;
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
;
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
;
657 /* Propogate values to generate correct vertices when vertex
660 if (purge_flags
& generated
)
661 _tnl_fixup_3f( tmp
->Normal
.data
, flags
, 0,
665 (VERT_EVAL_ANY
&~purge_flags
) );
670 /* In the AutoNormal case, the copy and assignment of tmp->NormalPtr
676 /* This copy may already have occurred when eliminating
679 if (coord
!= store
->Obj
+ IM
->CopyStart
)
680 copy_4f( store
->Obj
+ IM
->CopyStart
, tmp
->Obj
.data
, copycount
);
684 tmp
->Obj
.data
= store
->Obj
+ IM
->CopyStart
;
685 tmp
->Obj
.start
= (GLfloat
*)tmp
->Obj
.data
;
687 /* Note: Normal data is already prepared above.
691 if (ctx
->Eval
.Map1Vertex4
) {
692 eval1_4f( &tmp
->Obj
, coord
, flags
, 4,
693 &ctx
->EvalMap
.Map1Vertex4
);
695 else if (ctx
->Eval
.Map1Vertex3
) {
696 eval1_4f( &tmp
->Obj
, coord
, flags
, 3,
697 &ctx
->EvalMap
.Map1Vertex3
);
702 if (ctx
->Eval
.Map2Vertex4
)
704 if (ctx
->Eval
.AutoNormal
&& (req
& VERT_NORM
))
705 eval2_obj_norm( &tmp
->Obj
, &tmp
->Normal
, coord
, flags
, 4,
706 &ctx
->EvalMap
.Map2Vertex4
);
708 eval2_4f( &tmp
->Obj
, coord
, flags
, 4,
709 &ctx
->EvalMap
.Map2Vertex4
);
711 else if (ctx
->Eval
.Map2Vertex3
)
713 if (ctx
->Eval
.AutoNormal
&& (req
& VERT_NORM
))
714 eval2_obj_norm( &tmp
->Obj
, &tmp
->Normal
, coord
, flags
, 3,
715 &ctx
->EvalMap
.Map2Vertex3
);
717 eval2_4f( &tmp
->Obj
, coord
, flags
, 3,
718 &ctx
->EvalMap
.Map2Vertex3
);
724 /* Calculate new IM->Elts, IM->Primitive, IM->PrimitiveLength for
725 * the case where vertex maps are not enabled for some received eval
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
;
736 fprintf(stderr
, "PURGING\n");
738 for (i
= 0, j
= 0 ; i
< count
; i
++) {
739 if (flags
[i
] & vertex
) {
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
];
751 VB
->Elts
= store
->Elt
;
752 _tnl_get_purged_copy_verts( ctx
, store
);
755 /* Produce new flags array:
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. */