1 /* $Id: t_imm_eval.c,v 1.21 2002/01/22 14:35:16 brianp 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.
27 * Keith Whitwell <keithw@valinux.com>
39 #include "math/m_eval.h"
41 #include "t_context.h"
42 #include "t_imm_debug.h"
43 #include "t_imm_eval.h"
44 #include "t_imm_exec.h"
45 #include "t_imm_fixup.h"
46 #include "t_imm_alloc.h"
49 static void eval_points1( GLfloat outcoord
[][4],
52 GLfloat du
, GLfloat u1
)
55 for (i
= 0 ; !(flags
[i
] & VERT_BIT_END_VB
) ; i
++)
56 if (flags
[i
] & VERT_BITS_EVAL_ANY
) {
57 outcoord
[i
][0] = coord
[i
][0];
58 outcoord
[i
][1] = coord
[i
][1];
59 if (flags
[i
] & VERT_BIT_EVAL_P1
)
60 outcoord
[i
][0] = coord
[i
][0] * du
+ u1
;
64 static void eval_points2( GLfloat outcoord
[][4],
67 GLfloat du
, GLfloat u1
,
68 GLfloat dv
, GLfloat v1
)
71 for (i
= 0 ; !(flags
[i
] & VERT_BIT_END_VB
) ; i
++) {
72 if (flags
[i
] & VERT_BITS_EVAL_ANY
) {
73 outcoord
[i
][0] = coord
[i
][0];
74 outcoord
[i
][1] = coord
[i
][1];
75 if (flags
[i
] & VERT_BIT_EVAL_P2
) {
76 outcoord
[i
][0] = coord
[i
][0] * du
+ u1
;
77 outcoord
[i
][1] = coord
[i
][1] * dv
+ v1
;
83 static const GLubyte dirty_flags
[5] = {
92 static void eval1_4f( GLvector4f
*dest
,
96 struct gl_1d_map
*map
)
98 const GLfloat u1
= map
->u1
;
99 const GLfloat du
= map
->du
;
100 GLfloat (*to
)[4] = dest
->data
;
103 for (i
= 0 ; !(flags
[i
] & VERT_BIT_END_VB
) ; i
++)
104 if (flags
[i
] & (VERT_BIT_EVAL_C1
|VERT_BIT_EVAL_P1
)) {
105 GLfloat u
= (coord
[i
][0] - u1
) * du
;
106 ASSIGN_4V(to
[i
], 0,0,0,1);
107 _math_horner_bezier_curve(map
->Points
, to
[i
], u
,
108 dimension
, map
->Order
);
111 dest
->size
= MAX2(dest
->size
, dimension
);
112 dest
->flags
|= dirty_flags
[dimension
];
115 static void eval1_4f_ca( struct gl_client_array
*dest
,
119 struct gl_1d_map
*map
)
121 const GLfloat u1
= map
->u1
;
122 const GLfloat du
= map
->du
;
123 GLfloat (*to
)[4] = (GLfloat (*)[4])dest
->Ptr
;
126 ASSERT(dest
->Type
== GL_FLOAT
);
127 ASSERT(dest
->StrideB
== 4 * sizeof(GLfloat
));
129 for (i
= 0 ; !(flags
[i
] & VERT_BIT_END_VB
) ; i
++)
130 if (flags
[i
] & (VERT_BIT_EVAL_C1
|VERT_BIT_EVAL_P1
)) {
131 GLfloat u
= (coord
[i
][0] - u1
) * du
;
132 ASSIGN_4V(to
[i
], 0,0,0,1);
133 _math_horner_bezier_curve(map
->Points
, to
[i
], u
,
134 dimension
, map
->Order
);
137 dest
->Size
= MAX2(dest
->Size
, (GLint
) dimension
);
141 static void eval1_1ui( GLvector1ui
*dest
,
144 struct gl_1d_map
*map
)
146 const GLfloat u1
= map
->u1
;
147 const GLfloat du
= map
->du
;
148 GLuint
*to
= dest
->data
;
151 for (i
= 0 ; !(flags
[i
] & VERT_BIT_END_VB
) ; i
++)
152 if (flags
[i
] & (VERT_BIT_EVAL_C1
|VERT_BIT_EVAL_P1
)) {
153 GLfloat u
= (coord
[i
][0] - u1
) * du
;
155 _math_horner_bezier_curve(map
->Points
, &tmp
, u
, 1, map
->Order
);
156 to
[i
] = (GLuint
) (GLint
) tmp
;
161 static void eval1_norm( GLvector4f
*dest
,
164 struct gl_1d_map
*map
)
166 const GLfloat u1
= map
->u1
;
167 const GLfloat du
= map
->du
;
168 GLfloat (*to
)[4] = dest
->data
;
171 for (i
= 0 ; !(flags
[i
] & VERT_BIT_END_VB
) ; i
++)
172 if (flags
[i
] & (VERT_BIT_EVAL_C1
|VERT_BIT_EVAL_P1
)) {
173 GLfloat u
= (coord
[i
][0] - u1
) * du
;
174 _math_horner_bezier_curve(map
->Points
, to
[i
], u
, 3, map
->Order
);
182 static void eval2_obj_norm( GLvector4f
*obj_ptr
,
183 GLvector4f
*norm_ptr
,
187 struct gl_2d_map
*map
)
189 const GLfloat u1
= map
->u1
;
190 const GLfloat du
= map
->du
;
191 const GLfloat v1
= map
->v1
;
192 const GLfloat dv
= map
->dv
;
193 GLfloat (*obj
)[4] = obj_ptr
->data
;
194 GLfloat (*normal
)[4] = norm_ptr
->data
;
197 /* fprintf(stderr, "%s\n", __FUNCTION__); */
199 for (i
= 0 ; !(flags
[i
] & VERT_BIT_END_VB
) ; i
++)
200 if (flags
[i
] & (VERT_BIT_EVAL_C2
|VERT_BIT_EVAL_P2
)) {
201 GLfloat u
= (coord
[i
][0] - u1
) * du
;
202 GLfloat v
= (coord
[i
][1] - v1
) * dv
;
203 GLfloat du
[4], dv
[4];
205 ASSIGN_4V(obj
[i
], 0,0,0,1);
206 _math_de_casteljau_surf(map
->Points
, obj
[i
], du
, dv
, u
, v
, dimension
,
207 map
->Uorder
, map
->Vorder
);
209 if (dimension
== 4) {
210 du
[0] = du
[0]*obj
[i
][3] - du
[3]*obj
[i
][0];
211 du
[1] = du
[1]*obj
[i
][3] - du
[3]*obj
[i
][1];
212 du
[2] = du
[2]*obj
[i
][3] - du
[3]*obj
[i
][2];
214 dv
[0] = dv
[0]*obj
[i
][3] - dv
[3]*obj
[i
][0];
215 dv
[1] = dv
[1]*obj
[i
][3] - dv
[3]*obj
[i
][1];
216 dv
[2] = dv
[2]*obj
[i
][3] - dv
[3]*obj
[i
][2];
219 CROSS3(normal
[i
], du
, dv
);
220 NORMALIZE_3FV(normal
[i
]);
223 obj_ptr
->size
= MAX2(obj_ptr
->size
, dimension
);
224 obj_ptr
->flags
|= dirty_flags
[dimension
];
228 static void eval2_4f( GLvector4f
*dest
,
232 struct gl_2d_map
*map
)
234 const GLfloat u1
= map
->u1
;
235 const GLfloat du
= map
->du
;
236 const GLfloat v1
= map
->v1
;
237 const GLfloat dv
= map
->dv
;
238 GLfloat (*to
)[4] = dest
->data
;
241 for (i
= 0 ; !(flags
[i
] & VERT_BIT_END_VB
) ; i
++)
242 if (flags
[i
] & (VERT_BIT_EVAL_C2
|VERT_BIT_EVAL_P2
)) {
243 GLfloat u
= (coord
[i
][0] - u1
) * du
;
244 GLfloat v
= (coord
[i
][1] - v1
) * dv
;
245 /* fprintf(stderr, "coord %d: %f %f\n", i, coord[i][0], coord[i][1]); */
247 _math_horner_bezier_surf(map
->Points
, to
[i
], u
, v
, dimension
,
248 map
->Uorder
, map
->Vorder
);
251 dest
->size
= MAX2(dest
->size
, dimension
);
252 dest
->flags
|= dirty_flags
[dimension
];
255 static void eval2_4f_ca( struct gl_client_array
*dest
,
259 struct gl_2d_map
*map
)
261 const GLfloat u1
= map
->u1
;
262 const GLfloat du
= map
->du
;
263 const GLfloat v1
= map
->v1
;
264 const GLfloat dv
= map
->dv
;
265 GLfloat (*to
)[4] = (GLfloat (*)[4])dest
->Ptr
;
268 ASSERT(dest
->Type
== GL_FLOAT
);
269 ASSERT(dest
->StrideB
== 4 * sizeof(GLfloat
));
271 for (i
= 0 ; !(flags
[i
] & VERT_BIT_END_VB
) ; i
++)
272 if (flags
[i
] & (VERT_BIT_EVAL_C2
|VERT_BIT_EVAL_P2
)) {
273 GLfloat u
= (coord
[i
][0] - u1
) * du
;
274 GLfloat v
= (coord
[i
][1] - v1
) * dv
;
275 _math_horner_bezier_surf(map
->Points
, to
[i
], u
, v
, dimension
,
276 map
->Uorder
, map
->Vorder
);
279 dest
->Size
= MAX2(dest
->Size
, (GLint
) dimension
);
283 static void eval2_norm( GLvector4f
*dest
,
286 struct gl_2d_map
*map
)
288 const GLfloat u1
= map
->u1
;
289 const GLfloat du
= map
->du
;
290 const GLfloat v1
= map
->v1
;
291 const GLfloat dv
= map
->dv
;
292 GLfloat (*to
)[4] = dest
->data
;
295 for (i
= 0 ; !(flags
[i
] & VERT_BIT_END_VB
) ; i
++) {
296 if (flags
[i
] & (VERT_BIT_EVAL_C2
|VERT_BIT_EVAL_P2
)) {
297 GLfloat u
= (coord
[i
][0] - u1
) * du
;
298 GLfloat v
= (coord
[i
][1] - v1
) * dv
;
299 _math_horner_bezier_surf(map
->Points
, to
[i
], u
, v
, 3,
300 map
->Uorder
, map
->Vorder
);
306 static void eval2_1ui( GLvector1ui
*dest
,
309 struct gl_2d_map
*map
)
311 const GLfloat u1
= map
->u1
;
312 const GLfloat du
= map
->du
;
313 const GLfloat v1
= map
->v1
;
314 const GLfloat dv
= map
->dv
;
315 GLuint
*to
= dest
->data
;
318 for (i
= 0 ; !(flags
[i
] & VERT_BIT_END_VB
) ; i
++)
319 if (flags
[i
] & (VERT_BIT_EVAL_C2
|VERT_BIT_EVAL_P2
)) {
320 GLfloat u
= (coord
[i
][0] - u1
) * du
;
321 GLfloat v
= (coord
[i
][1] - v1
) * dv
;
323 _math_horner_bezier_surf(map
->Points
, &tmp
, u
, v
, 1,
324 map
->Uorder
, map
->Vorder
);
326 to
[i
] = (GLuint
) (GLint
) tmp
;
335 static void copy_4f( GLfloat to
[][4], GLfloat from
[][4], GLuint count
)
337 MEMCPY( to
, from
, count
* sizeof(to
[0]));
340 static void copy_4f_stride( GLfloat to
[][4], GLfloat
*from
,
341 GLuint stride
, GLuint count
)
343 if (stride
== 4 * sizeof(GLfloat
))
344 MEMCPY( to
, from
, count
* sizeof(to
[0]));
347 /* fprintf(stderr, "%s stride %d count %d\n", __FUNCTION__, */
348 /* stride, count); */
349 for (i
= 0 ; i
< count
; i
++, STRIDE_F(from
, stride
))
350 COPY_4FV( to
[i
], from
);
354 static void copy_3f( GLfloat to
[][4], GLfloat from
[][4], GLuint count
)
357 /* MEMCPY( to, from, (count) * sizeof(to[0])); */
358 for (i
= 0 ; i
< count
; i
++) {
359 /* fprintf(stderr, "copy norm %d from %p: %f %f %f\n", i, */
361 /* from[i][0], from[i][1], from[i][2]); */
362 COPY_3FV(to
[i
], from
[i
]);
367 static void copy_1ui( GLuint to
[], GLuint from
[], GLuint count
)
369 MEMCPY( to
, from
, (count
) * sizeof(to
[0]));
374 /* Translate eval enabled flags to VERT_* flags.
376 static void update_eval( GLcontext
*ctx
)
378 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
379 GLuint eval1
= 0, eval2
= 0;
381 if (ctx
->Eval
.Map1Index
)
382 eval1
|= VERT_BIT_INDEX
;
384 if (ctx
->Eval
.Map2Index
)
385 eval2
|= VERT_BIT_INDEX
;
387 if (ctx
->Eval
.Map1Color4
)
388 eval1
|= VERT_BIT_COLOR0
;
390 if (ctx
->Eval
.Map2Color4
)
391 eval2
|= VERT_BIT_COLOR0
;
393 if (ctx
->Eval
.Map1Normal
)
394 eval1
|= VERT_BIT_NORMAL
;
396 if (ctx
->Eval
.Map2Normal
)
397 eval2
|= VERT_BIT_NORMAL
;
399 if (ctx
->Eval
.Map1TextureCoord4
||
400 ctx
->Eval
.Map1TextureCoord3
||
401 ctx
->Eval
.Map1TextureCoord2
||
402 ctx
->Eval
.Map1TextureCoord1
)
403 eval1
|= VERT_BIT_TEX0
;
405 if (ctx
->Eval
.Map2TextureCoord4
||
406 ctx
->Eval
.Map2TextureCoord3
||
407 ctx
->Eval
.Map2TextureCoord2
||
408 ctx
->Eval
.Map2TextureCoord1
)
409 eval2
|= VERT_BIT_TEX0
;
411 if (ctx
->Eval
.Map1Vertex4
)
412 eval1
|= VERT_BITS_OBJ_234
;
414 if (ctx
->Eval
.Map1Vertex3
)
415 eval1
|= VERT_BITS_OBJ_23
;
417 if (ctx
->Eval
.Map2Vertex4
) {
418 if (ctx
->Eval
.AutoNormal
)
419 eval2
|= VERT_BITS_OBJ_234
| VERT_BIT_NORMAL
;
421 eval2
|= VERT_BITS_OBJ_234
;
423 else if (ctx
->Eval
.Map2Vertex3
) {
424 if (ctx
->Eval
.AutoNormal
)
425 eval2
|= VERT_BITS_OBJ_23
| VERT_BIT_NORMAL
;
427 eval2
|= VERT_BITS_OBJ_23
;
430 tnl
->eval
.EvalMap1Flags
= eval1
;
431 tnl
->eval
.EvalMap2Flags
= eval2
;
432 tnl
->eval
.EvalNewState
= 0;
436 /* This looks a lot like a pipeline stage, but for various reasons is
437 * better handled outside the pipeline, and considered the final stage
438 * of fixing up an immediate struct for execution.
440 * Really want to cache the results of this function in display lists,
441 * at least for EvalMesh commands.
443 void _tnl_eval_immediate( GLcontext
*ctx
, struct immediate
*IM
)
445 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
446 struct vertex_arrays
*tmp
= &tnl
->imm_inputs
;
447 struct immediate
*store
= tnl
->eval
.im
;
448 GLuint
*flags
= IM
->Flag
+ IM
->CopyStart
;
450 GLuint orflag
= IM
->OrFlag
;
451 GLuint any_eval1
= orflag
& (VERT_BIT_EVAL_C1
|VERT_BIT_EVAL_P1
);
452 GLuint any_eval2
= orflag
& (VERT_BIT_EVAL_C2
|VERT_BIT_EVAL_P2
);
454 GLuint purge_flags
= 0;
455 GLfloat (*coord
)[4] = IM
->Attrib
[VERT_ATTRIB_POS
] + IM
->CopyStart
;
457 if (IM
->AndFlag
& VERT_BITS_EVAL_ANY
)
458 copycount
= IM
->Start
- IM
->CopyStart
; /* just copy copied vertices */
460 copycount
= IM
->Count
- IM
->CopyStart
; /* copy all vertices */
462 /* fprintf(stderr, "%s copystart %d start %d count %d copycount %d\n", */
463 /* __FUNCTION__, IM->CopyStart, IM->Start, IM->Count, copycount); */
466 store
= tnl
->eval
.im
= _tnl_alloc_immediate( ctx
);
468 if (tnl
->eval
.EvalNewState
& _NEW_EVAL
)
472 req
|= tnl
->pipeline
.inputs
& tnl
->eval
.EvalMap1Flags
;
474 if (!ctx
->Eval
.Map1Vertex4
&& !ctx
->Eval
.Map1Vertex3
)
475 purge_flags
= (VERT_BIT_EVAL_P1
|VERT_BIT_EVAL_C1
);
477 if (orflag
& VERT_BIT_EVAL_P1
) {
478 eval_points1( store
->Attrib
[VERT_ATTRIB_POS
] + IM
->CopyStart
,
480 ctx
->Eval
.MapGrid1du
,
481 ctx
->Eval
.MapGrid1u1
);
483 coord
= store
->Attrib
[VERT_ATTRIB_POS
] + IM
->CopyStart
;
488 req
|= tnl
->pipeline
.inputs
& tnl
->eval
.EvalMap2Flags
;
490 if (!ctx
->Eval
.Map2Vertex4
&& !ctx
->Eval
.Map2Vertex3
)
491 purge_flags
|= (VERT_BIT_EVAL_P2
|VERT_BIT_EVAL_C2
);
493 if (orflag
& VERT_BIT_EVAL_P2
) {
494 eval_points2( store
->Attrib
[VERT_ATTRIB_POS
] + IM
->CopyStart
,
496 ctx
->Eval
.MapGrid2du
,
497 ctx
->Eval
.MapGrid2u1
,
498 ctx
->Eval
.MapGrid2dv
,
499 ctx
->Eval
.MapGrid2v1
);
501 coord
= store
->Attrib
[VERT_ATTRIB_POS
] + IM
->CopyStart
;
506 /* _tnl_print_vert_flags(__FUNCTION__, req); */
508 /* Perform the evaluations on active data elements.
510 if (req
& VERT_BIT_INDEX
)
512 GLuint generated
= 0;
515 copy_1ui( store
->Index
+ IM
->CopyStart
, tmp
->Index
.data
, copycount
);
517 tmp
->Index
.data
= store
->Index
+ IM
->CopyStart
;
518 tmp
->Index
.start
= store
->Index
+ IM
->CopyStart
;
520 if (ctx
->Eval
.Map1Index
&& any_eval1
) {
521 eval1_1ui( &tmp
->Index
, coord
, flags
, &ctx
->EvalMap
.Map1Index
);
522 generated
|= VERT_BIT_EVAL_C1
|VERT_BIT_EVAL_P1
;
525 if (ctx
->Eval
.Map2Index
&& any_eval2
) {
526 eval2_1ui( &tmp
->Index
, coord
, flags
, &ctx
->EvalMap
.Map2Index
);
527 generated
|= VERT_BIT_EVAL_C2
|VERT_BIT_EVAL_P2
;
531 if (req
& VERT_BIT_COLOR0
)
533 GLuint generated
= 0;
536 copy_4f_stride( store
->Attrib
[VERT_ATTRIB_COLOR0
] + IM
->CopyStart
,
537 (GLfloat
*)tmp
->Color
.Ptr
,
541 tmp
->Color
.Ptr
= store
->Attrib
[VERT_ATTRIB_COLOR0
] + IM
->CopyStart
;
542 tmp
->Color
.StrideB
= 4 * sizeof(GLfloat
);
543 tmp
->Color
.Flags
= 0;
544 tnl
->vb
.importable_data
&= ~VERT_BIT_COLOR0
;
546 if (ctx
->Eval
.Map1Color4
&& any_eval1
) {
547 eval1_4f_ca( &tmp
->Color
, coord
, flags
, 4, &ctx
->EvalMap
.Map1Color4
);
548 generated
|= VERT_BIT_EVAL_C1
|VERT_BIT_EVAL_P1
;
551 if (ctx
->Eval
.Map2Color4
&& any_eval2
) {
552 eval2_4f_ca( &tmp
->Color
, coord
, flags
, 4, &ctx
->EvalMap
.Map2Color4
);
553 generated
|= VERT_BIT_EVAL_C2
|VERT_BIT_EVAL_P2
;
558 if (req
& VERT_BIT_TEX(0))
560 GLuint generated
= 0;
563 copy_4f( store
->Attrib
[VERT_ATTRIB_TEX0
] + IM
->CopyStart
,
564 tmp
->TexCoord
[0].data
, copycount
);
566 tmp
->TexCoord
[0].size
= 0;
568 tmp
->TexCoord
[0].data
= store
->Attrib
[VERT_ATTRIB_TEX0
] + 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_BIT_EVAL_C1
|VERT_BIT_EVAL_P1
;
577 else if (ctx
->Eval
.Map1TextureCoord3
) {
578 eval1_4f( &tmp
->TexCoord
[0], coord
, flags
, 3,
579 &ctx
->EvalMap
.Map1Texture3
);
580 generated
|= VERT_BIT_EVAL_C1
|VERT_BIT_EVAL_P1
;
582 else if (ctx
->Eval
.Map1TextureCoord2
) {
583 eval1_4f( &tmp
->TexCoord
[0], coord
, flags
, 2,
584 &ctx
->EvalMap
.Map1Texture2
);
585 generated
|= VERT_BIT_EVAL_C1
|VERT_BIT_EVAL_P1
;
587 else if (ctx
->Eval
.Map1TextureCoord1
) {
588 eval1_4f( &tmp
->TexCoord
[0], coord
, flags
, 1,
589 &ctx
->EvalMap
.Map1Texture1
);
590 generated
|= VERT_BIT_EVAL_C1
|VERT_BIT_EVAL_P1
;
595 if (ctx
->Eval
.Map2TextureCoord4
) {
596 eval2_4f( &tmp
->TexCoord
[0], coord
, flags
, 4,
597 &ctx
->EvalMap
.Map2Texture4
);
598 generated
|= VERT_BIT_EVAL_C2
|VERT_BIT_EVAL_P2
;
600 else if (ctx
->Eval
.Map2TextureCoord3
) {
601 eval2_4f( &tmp
->TexCoord
[0], coord
, flags
, 3,
602 &ctx
->EvalMap
.Map2Texture3
);
603 generated
|= VERT_BIT_EVAL_C2
|VERT_BIT_EVAL_P2
;
605 else if (ctx
->Eval
.Map2TextureCoord2
) {
606 eval2_4f( &tmp
->TexCoord
[0], coord
, flags
, 2,
607 &ctx
->EvalMap
.Map2Texture2
);
608 generated
|= VERT_BIT_EVAL_C2
|VERT_BIT_EVAL_P2
;
610 else if (ctx
->Eval
.Map2TextureCoord1
) {
611 eval2_4f( &tmp
->TexCoord
[0], coord
, flags
, 1,
612 &ctx
->EvalMap
.Map2Texture1
);
613 generated
|= VERT_BIT_EVAL_C2
|VERT_BIT_EVAL_P2
;
619 if (req
& VERT_BIT_NORMAL
)
621 GLuint generated
= 0;
624 /* fprintf(stderr, "%s: Copy normals\n", __FUNCTION__); */
625 copy_3f( store
->Attrib
[VERT_ATTRIB_NORMAL
] + IM
->CopyStart
,
626 tmp
->Normal
.data
, copycount
);
629 tmp
->Normal
.data
= store
->Attrib
[VERT_ATTRIB_NORMAL
] + IM
->CopyStart
;
630 tmp
->Normal
.start
= (GLfloat
*)tmp
->Normal
.data
;
632 if (ctx
->Eval
.Map1Normal
&& any_eval1
) {
633 eval1_norm( &tmp
->Normal
, coord
, flags
, &ctx
->EvalMap
.Map1Normal
);
634 generated
|= VERT_BIT_EVAL_C1
|VERT_BIT_EVAL_P1
;
637 if (ctx
->Eval
.Map2Normal
&& any_eval2
) {
638 eval2_norm( &tmp
->Normal
, coord
, flags
, &ctx
->EvalMap
.Map2Normal
);
639 generated
|= VERT_BIT_EVAL_C2
|VERT_BIT_EVAL_P2
;
645 /* In the AutoNormal case, the copy and assignment of tmp->NormalPtr
648 if (req
& VERT_BIT_POS
)
651 /* This copy may already have occurred when eliminating
654 if (coord
!= store
->Attrib
[VERT_ATTRIB_POS
] + IM
->CopyStart
) {
655 copy_4f( store
->Attrib
[VERT_ATTRIB_POS
] + IM
->CopyStart
,
656 tmp
->Obj
.data
, copycount
);
663 tmp
->Obj
.data
= store
->Attrib
[VERT_ATTRIB_POS
] + IM
->CopyStart
;
664 tmp
->Obj
.start
= (GLfloat
*)tmp
->Obj
.data
;
666 /* Note: Normal data is already prepared above.
670 if (ctx
->Eval
.Map1Vertex4
) {
671 eval1_4f( &tmp
->Obj
, coord
, flags
, 4,
672 &ctx
->EvalMap
.Map1Vertex4
);
674 else if (ctx
->Eval
.Map1Vertex3
) {
675 eval1_4f( &tmp
->Obj
, coord
, flags
, 3,
676 &ctx
->EvalMap
.Map1Vertex3
);
681 if (ctx
->Eval
.Map2Vertex4
) {
682 if (ctx
->Eval
.AutoNormal
&& (req
& VERT_BIT_NORMAL
))
683 eval2_obj_norm( &tmp
->Obj
, &tmp
->Normal
, coord
, flags
, 4,
684 &ctx
->EvalMap
.Map2Vertex4
);
686 eval2_4f( &tmp
->Obj
, coord
, flags
, 4,
687 &ctx
->EvalMap
.Map2Vertex4
);
689 else if (ctx
->Eval
.Map2Vertex3
) {
690 if (ctx
->Eval
.AutoNormal
&& (req
& VERT_BIT_NORMAL
))
691 eval2_obj_norm( &tmp
->Obj
, &tmp
->Normal
, coord
, flags
, 3,
692 &ctx
->EvalMap
.Map2Vertex3
);
694 eval2_4f( &tmp
->Obj
, coord
, flags
, 3,
695 &ctx
->EvalMap
.Map2Vertex3
);
701 /* Calculate new IM->Elts, IM->Primitive, IM->PrimitiveLength for
702 * the case where vertex maps are not enabled for some received
703 * eval coordinates. In this case those slots in the immediate
707 GLuint vertex
= VERT_BIT_POS
|(VERT_BITS_EVAL_ANY
& ~purge_flags
);
708 GLuint last_new_prim
= 0;
709 GLuint new_prim_length
= 0;
710 GLuint next_old_prim
= 0;
711 struct vertex_buffer
*VB
= &tnl
->vb
;
712 GLuint i
,j
,count
= VB
->Count
;
714 /* fprintf(stderr, "PURGING\n"); */
716 for (i
= 0, j
= 0 ; i
< count
; i
++) {
717 if (flags
[i
] & vertex
) {
721 if (i
== next_old_prim
) {
722 next_old_prim
+= VB
->PrimitiveLength
[i
];
723 VB
->PrimitiveLength
[last_new_prim
] = new_prim_length
;
724 VB
->Primitive
[j
] = VB
->Primitive
[i
];
729 VB
->Elts
= store
->Elt
;
730 _tnl_get_purged_copy_verts( ctx
, store
);
733 /* Produce new flags array:
737 GLuint count
= tnl
->vb
.Count
+ 1;
739 copy_1ui( store
->Flag
, flags
, count
);
740 tnl
->vb
.Flag
= store
->Flag
;
741 for (i
= 0 ; i
< count
; i
++)
742 store
->Flag
[i
] |= req
;
743 IM
->Evaluated
= req
; /* hack for copying. */