3 * Mesa 3-D graphics library
5 * Copyright (C) 1995-2000 Brian Paul
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the Free
19 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 * NURBS implementation written by Bogdan Sikorski (bogdan@cira.it)
25 * See README2 for more info.
41 get_surface_dim(GLenum type
)
44 case GL_MAP2_VERTEX_3
:
46 case GL_MAP2_VERTEX_4
:
54 case GL_MAP2_TEXTURE_COORD_1
:
56 case GL_MAP2_TEXTURE_COORD_2
:
58 case GL_MAP2_TEXTURE_COORD_3
:
60 case GL_MAP2_TEXTURE_COORD_4
:
63 abort(); /* TODO: is this OK? */
65 return 0; /*never get here */
69 test_nurbs_surface(GLUnurbsObj
* nobj
, surface_attribs
* attrib
)
74 if (attrib
->sorder
< 0 || attrib
->torder
< 0) {
75 call_user_error(nobj
, GLU_INVALID_VALUE
);
78 glGetIntegerv(GL_MAX_EVAL_ORDER
, &tmp_int
);
79 if (attrib
->sorder
> tmp_int
|| attrib
->sorder
< 2) {
80 call_user_error(nobj
, GLU_NURBS_ERROR1
);
83 if (attrib
->torder
> tmp_int
|| attrib
->torder
< 2) {
84 call_user_error(nobj
, GLU_NURBS_ERROR1
);
87 if (attrib
->sknot_count
< attrib
->sorder
+ 2) {
88 call_user_error(nobj
, GLU_NURBS_ERROR2
);
91 if (attrib
->tknot_count
< attrib
->torder
+ 2) {
92 call_user_error(nobj
, GLU_NURBS_ERROR2
);
95 if (attrib
->s_stride
< 0 || attrib
->t_stride
< 0) {
96 call_user_error(nobj
, GLU_NURBS_ERROR34
);
99 if (attrib
->sknot
== NULL
|| attrib
->tknot
== NULL
100 || attrib
->ctrlarray
== NULL
) {
101 call_user_error(nobj
, GLU_NURBS_ERROR36
);
104 if ((err
= test_knot(attrib
->tknot_count
, attrib
->tknot
, attrib
->torder
))
106 call_user_error(nobj
, err
);
109 if ((err
= test_knot(attrib
->sknot_count
, attrib
->sknot
, attrib
->sorder
))
111 call_user_error(nobj
, err
);
118 test_nurbs_surfaces(GLUnurbsObj
* nobj
)
120 /* test the geometric data */
121 if (test_nurbs_surface(nobj
, &(nobj
->surface
.geom
)) != GLU_NO_ERROR
)
123 /* now test the attributive data */
125 if (nobj
->surface
.color
.type
!= GLU_INVALID_ENUM
)
126 if (test_nurbs_surface(nobj
, &(nobj
->surface
.color
)) != GLU_NO_ERROR
)
129 if (nobj
->surface
.normal
.type
!= GLU_INVALID_ENUM
)
130 if (test_nurbs_surface(nobj
, &(nobj
->surface
.normal
)) != GLU_NO_ERROR
)
133 if (nobj
->surface
.texture
.type
!= GLU_INVALID_ENUM
)
134 if (test_nurbs_surface(nobj
, &(nobj
->surface
.texture
)) != GLU_NO_ERROR
)
140 convert_surf(knot_str_type
* s_knot
, knot_str_type
* t_knot
,
141 surface_attribs
* attrib
, GLfloat
** new_ctrl
,
142 GLint
* s_n_ctrl
, GLint
* t_n_ctrl
)
145 GLfloat
*ctrl_offset
;
147 GLint i
, j
, t_cnt
, s_cnt
;
152 /* valid range is empty? */
153 if ((s_knot
->unified_knot
!= NULL
&& s_knot
->unified_nknots
== 0) ||
154 (t_knot
->unified_knot
!= NULL
&& t_knot
->unified_nknots
== 0)) {
155 if (s_knot
->unified_knot
) {
156 free(s_knot
->unified_knot
);
157 s_knot
->unified_knot
= NULL
;
159 if (t_knot
->unified_knot
) {
160 free(t_knot
->unified_knot
);
161 t_knot
->unified_knot
= NULL
;
167 t_cnt
= attrib
->tknot_count
- attrib
->torder
;
168 s_cnt
= attrib
->sknot_count
- attrib
->sorder
;
169 if ((tmp_ctrl
= (GLfloat
**) malloc(sizeof(GLfloat
*) * t_cnt
)) == NULL
)
170 return GLU_OUT_OF_MEMORY
;
171 if ((err
= explode_knot(s_knot
)) != GLU_NO_ERROR
) {
173 if (s_knot
->unified_knot
) {
174 free(s_knot
->unified_knot
);
175 s_knot
->unified_knot
= NULL
;
179 if (s_knot
->unified_knot
) {
180 free(s_knot
->unified_knot
);
181 s_knot
->unified_knot
= NULL
;
183 if ((err
= calc_alphas(s_knot
)) != GLU_NO_ERROR
) {
185 free(s_knot
->new_knot
);
188 free(s_knot
->new_knot
);
189 ctrl_offset
= attrib
->ctrlarray
;
191 for (i
= 0; i
< t_cnt
; i
++) {
192 if ((err
= calc_new_ctrl_pts(ctrl_offset
, attrib
->s_stride
, s_knot
,
194 &tmp_n_control
)) != GLU_NO_ERROR
) {
195 for (--i
; i
<= 0; i
--)
201 ctrl_offset
+= attrib
->t_stride
;
204 tmp_stride
= dim
* tmp_n_control
;
205 if ((*new_ctrl
= (GLfloat
*) malloc(sizeof(GLfloat
) * tmp_stride
* t_cnt
))
207 for (i
= 0; i
< t_cnt
; i
++)
210 return GLU_OUT_OF_MEMORY
;
212 for (i
= 0; i
< tmp_n_control
; i
++)
213 for (j
= 0; j
< t_cnt
; j
++)
214 MEMCPY(*new_ctrl
+ j
* dim
+ i
* dim
* t_cnt
, tmp_ctrl
[j
] + dim
* i
,
215 sizeof(GLfloat
) * dim
);
216 for (i
= 0; i
< t_cnt
; i
++)
219 *s_n_ctrl
= tmp_n_control
;
221 if ((tmp_ctrl
= (GLfloat
**) malloc(sizeof(GLfloat
*) * (*s_n_ctrl
))) ==
223 return GLU_OUT_OF_MEMORY
;
225 if ((err
= explode_knot(t_knot
)) != GLU_NO_ERROR
) {
227 if (t_knot
->unified_knot
) {
228 free(t_knot
->unified_knot
);
229 t_knot
->unified_knot
= NULL
;
233 if (t_knot
->unified_knot
) {
234 free(t_knot
->unified_knot
);
235 t_knot
->unified_knot
= NULL
;
237 if ((err
= calc_alphas(t_knot
)) != GLU_NO_ERROR
) {
239 free(t_knot
->new_knot
);
242 free(t_knot
->new_knot
);
243 ctrl_offset
= *new_ctrl
;
244 for (i
= 0; i
< (*s_n_ctrl
); i
++) {
245 if ((err
= calc_new_ctrl_pts(ctrl_offset
, dim
, t_knot
,
247 &tmp_n_control
)) != GLU_NO_ERROR
) {
248 for (--i
; i
<= 0; i
--)
254 ctrl_offset
+= dim
* t_cnt
;
258 tmp_stride
= dim
* tmp_n_control
;
261 (GLfloat
*) malloc(sizeof(GLfloat
) * tmp_stride
* (*s_n_ctrl
))) ==
263 for (i
= 0; i
< (*s_n_ctrl
); i
++)
266 return GLU_OUT_OF_MEMORY
;
268 for (i
= 0; i
< (*s_n_ctrl
); i
++) {
269 MEMCPY(*new_ctrl
+ i
* tmp_stride
, tmp_ctrl
[i
],
270 sizeof(GLfloat
) * tmp_stride
);
274 *t_n_ctrl
= tmp_n_control
;
278 /* prepare the knot information structures */
280 fill_knot_structures(GLUnurbsObj
* nobj
,
281 knot_str_type
* geom_s_knot
, knot_str_type
* geom_t_knot
,
282 knot_str_type
* color_s_knot
,
283 knot_str_type
* color_t_knot
,
284 knot_str_type
* normal_s_knot
,
285 knot_str_type
* normal_t_knot
,
286 knot_str_type
* texture_s_knot
,
287 knot_str_type
* texture_t_knot
)
294 geom_s_knot
->unified_knot
= NULL
;
295 knot
= geom_s_knot
->knot
= nobj
->surface
.geom
.sknot
;
296 nknots
= geom_s_knot
->nknots
= nobj
->surface
.geom
.sknot_count
;
297 order
= geom_s_knot
->order
= nobj
->surface
.geom
.sorder
;
298 geom_s_knot
->delta_nknots
= 0;
299 t_min
= geom_s_knot
->t_min
= order
- 1;
300 t_max
= geom_s_knot
->t_max
= nknots
- order
;
301 if (fabs(knot
[t_min
] - knot
[t_max
]) < EPSILON
) {
302 call_user_error(nobj
, GLU_NURBS_ERROR3
);
305 if (fabs(knot
[0] - knot
[t_min
]) < EPSILON
) {
306 /* knot open at beggining */
307 geom_s_knot
->open_at_begin
= GL_TRUE
;
310 geom_s_knot
->open_at_begin
= GL_FALSE
;
311 if (fabs(knot
[t_max
] - knot
[nknots
- 1]) < EPSILON
) {
312 /* knot open at end */
313 geom_s_knot
->open_at_end
= GL_TRUE
;
316 geom_s_knot
->open_at_end
= GL_FALSE
;
317 geom_t_knot
->unified_knot
= NULL
;
318 knot
= geom_t_knot
->knot
= nobj
->surface
.geom
.tknot
;
319 nknots
= geom_t_knot
->nknots
= nobj
->surface
.geom
.tknot_count
;
320 order
= geom_t_knot
->order
= nobj
->surface
.geom
.torder
;
321 geom_t_knot
->delta_nknots
= 0;
322 t_min
= geom_t_knot
->t_min
= order
- 1;
323 t_max
= geom_t_knot
->t_max
= nknots
- order
;
324 if (fabs(knot
[t_min
] - knot
[t_max
]) < EPSILON
) {
325 call_user_error(nobj
, GLU_NURBS_ERROR3
);
328 if (fabs(knot
[0] - knot
[t_min
]) < EPSILON
) {
329 /* knot open at beggining */
330 geom_t_knot
->open_at_begin
= GL_TRUE
;
333 geom_t_knot
->open_at_begin
= GL_FALSE
;
334 if (fabs(knot
[t_max
] - knot
[nknots
- 1]) < EPSILON
) {
335 /* knot open at end */
336 geom_t_knot
->open_at_end
= GL_TRUE
;
339 geom_t_knot
->open_at_end
= GL_FALSE
;
341 if (nobj
->surface
.color
.type
!= GLU_INVALID_ENUM
) {
342 color_s_knot
->unified_knot
= (GLfloat
*) 1;
343 knot
= color_s_knot
->knot
= nobj
->surface
.color
.sknot
;
344 nknots
= color_s_knot
->nknots
= nobj
->surface
.color
.sknot_count
;
345 order
= color_s_knot
->order
= nobj
->surface
.color
.sorder
;
346 color_s_knot
->delta_nknots
= 0;
347 t_min
= color_s_knot
->t_min
= order
- 1;
348 t_max
= color_s_knot
->t_max
= nknots
- order
;
349 if (fabs(knot
[t_min
] - knot
[t_max
]) < EPSILON
) {
350 call_user_error(nobj
, GLU_NURBS_ERROR3
);
353 if (fabs(knot
[0] - knot
[t_min
]) < EPSILON
) {
354 /* knot open at beggining */
355 color_s_knot
->open_at_begin
= GL_TRUE
;
358 color_s_knot
->open_at_begin
= GL_FALSE
;
359 if (fabs(knot
[t_max
] - knot
[nknots
- 1]) < EPSILON
) {
360 /* knot open at end */
361 color_s_knot
->open_at_end
= GL_TRUE
;
364 color_s_knot
->open_at_end
= GL_FALSE
;
365 color_t_knot
->unified_knot
= (GLfloat
*) 1;
366 knot
= color_t_knot
->knot
= nobj
->surface
.color
.tknot
;
367 nknots
= color_t_knot
->nknots
= nobj
->surface
.color
.tknot_count
;
368 order
= color_t_knot
->order
= nobj
->surface
.color
.torder
;
369 color_t_knot
->delta_nknots
= 0;
370 t_min
= color_t_knot
->t_min
= order
- 1;
371 t_max
= color_t_knot
->t_max
= nknots
- order
;
372 if (fabs(knot
[t_min
] - knot
[t_max
]) < EPSILON
) {
373 call_user_error(nobj
, GLU_NURBS_ERROR3
);
376 if (fabs(knot
[0] - knot
[t_min
]) < EPSILON
) {
377 /* knot open at beggining */
378 color_t_knot
->open_at_begin
= GL_TRUE
;
381 color_t_knot
->open_at_begin
= GL_FALSE
;
382 if (fabs(knot
[t_max
] - knot
[nknots
- 1]) < EPSILON
) {
383 /* knot open at end */
384 color_t_knot
->open_at_end
= GL_TRUE
;
387 color_t_knot
->open_at_end
= GL_FALSE
;
390 color_s_knot
->unified_knot
= NULL
;
391 color_t_knot
->unified_knot
= NULL
;
394 if (nobj
->surface
.normal
.type
!= GLU_INVALID_ENUM
) {
395 normal_s_knot
->unified_knot
= (GLfloat
*) 1;
396 knot
= normal_s_knot
->knot
= nobj
->surface
.normal
.sknot
;
397 nknots
= normal_s_knot
->nknots
= nobj
->surface
.normal
.sknot_count
;
398 order
= normal_s_knot
->order
= nobj
->surface
.normal
.sorder
;
399 normal_s_knot
->delta_nknots
= 0;
400 t_min
= normal_s_knot
->t_min
= order
- 1;
401 t_max
= normal_s_knot
->t_max
= nknots
- order
;
402 if (fabs(knot
[t_min
] - knot
[t_max
]) < EPSILON
) {
403 call_user_error(nobj
, GLU_NURBS_ERROR3
);
406 if (fabs(knot
[0] - knot
[t_min
]) < EPSILON
) {
407 /* knot open at beggining */
408 normal_s_knot
->open_at_begin
= GL_TRUE
;
411 normal_s_knot
->open_at_begin
= GL_FALSE
;
412 if (fabs(knot
[t_max
] - knot
[nknots
- 1]) < EPSILON
) {
413 /* knot open at end */
414 normal_s_knot
->open_at_end
= GL_TRUE
;
417 normal_s_knot
->open_at_end
= GL_FALSE
;
418 normal_t_knot
->unified_knot
= (GLfloat
*) 1;
419 knot
= normal_t_knot
->knot
= nobj
->surface
.normal
.tknot
;
420 nknots
= normal_t_knot
->nknots
= nobj
->surface
.normal
.tknot_count
;
421 order
= normal_t_knot
->order
= nobj
->surface
.normal
.torder
;
422 normal_t_knot
->delta_nknots
= 0;
423 t_min
= normal_t_knot
->t_min
= order
- 1;
424 t_max
= normal_t_knot
->t_max
= nknots
- order
;
425 if (fabs(knot
[t_min
] - knot
[t_max
]) < EPSILON
) {
426 call_user_error(nobj
, GLU_NURBS_ERROR3
);
429 if (fabs(knot
[0] - knot
[t_min
]) < EPSILON
) {
430 /* knot open at beggining */
431 normal_t_knot
->open_at_begin
= GL_TRUE
;
434 normal_t_knot
->open_at_begin
= GL_FALSE
;
435 if (fabs(knot
[t_max
] - knot
[nknots
- 1]) < EPSILON
) {
436 /* knot open at end */
437 normal_t_knot
->open_at_end
= GL_TRUE
;
440 normal_t_knot
->open_at_end
= GL_FALSE
;
443 normal_s_knot
->unified_knot
= NULL
;
444 normal_t_knot
->unified_knot
= NULL
;
447 if (nobj
->surface
.texture
.type
!= GLU_INVALID_ENUM
) {
448 texture_s_knot
->unified_knot
= (GLfloat
*) 1;
449 knot
= texture_s_knot
->knot
= nobj
->surface
.texture
.sknot
;
450 nknots
= texture_s_knot
->nknots
= nobj
->surface
.texture
.sknot_count
;
451 order
= texture_s_knot
->order
= nobj
->surface
.texture
.sorder
;
452 texture_s_knot
->delta_nknots
= 0;
453 t_min
= texture_s_knot
->t_min
= order
- 1;
454 t_max
= texture_s_knot
->t_max
= nknots
- order
;
455 if (fabs(knot
[t_min
] - knot
[t_max
]) < EPSILON
) {
456 call_user_error(nobj
, GLU_NURBS_ERROR3
);
459 if (fabs(knot
[0] - knot
[t_min
]) < EPSILON
) {
460 /* knot open at beggining */
461 texture_s_knot
->open_at_begin
= GL_TRUE
;
464 texture_s_knot
->open_at_begin
= GL_FALSE
;
465 if (fabs(knot
[t_max
] - knot
[nknots
- 1]) < EPSILON
) {
466 /* knot open at end */
467 texture_s_knot
->open_at_end
= GL_TRUE
;
470 texture_s_knot
->open_at_end
= GL_FALSE
;
471 texture_t_knot
->unified_knot
= (GLfloat
*) 1;
472 knot
= texture_t_knot
->knot
= nobj
->surface
.texture
.tknot
;
473 nknots
= texture_t_knot
->nknots
= nobj
->surface
.texture
.tknot_count
;
474 order
= texture_t_knot
->order
= nobj
->surface
.texture
.torder
;
475 texture_t_knot
->delta_nknots
= 0;
476 t_min
= texture_t_knot
->t_min
= order
- 1;
477 t_max
= texture_t_knot
->t_max
= nknots
- order
;
478 if (fabs(knot
[t_min
] - knot
[t_max
]) < EPSILON
) {
479 call_user_error(nobj
, GLU_NURBS_ERROR3
);
482 if (fabs(knot
[0] - knot
[t_min
]) < EPSILON
) {
483 /* knot open at beggining */
484 texture_t_knot
->open_at_begin
= GL_TRUE
;
487 texture_t_knot
->open_at_begin
= GL_FALSE
;
488 if (fabs(knot
[t_max
] - knot
[nknots
- 1]) < EPSILON
) {
489 /* knot open at end */
490 texture_t_knot
->open_at_end
= GL_TRUE
;
493 texture_t_knot
->open_at_end
= GL_FALSE
;
496 texture_s_knot
->unified_knot
= NULL
;
497 texture_t_knot
->unified_knot
= NULL
;
504 free_new_ctrl(new_ctrl_type
* p
)
509 free(p
->geom_offsets
);
512 if (p
->color_offsets
)
513 free(p
->color_offsets
);
515 if (p
->normal_ctrl
) {
516 free(p
->normal_ctrl
);
517 if (p
->normal_offsets
)
518 free(p
->normal_offsets
);
520 if (p
->texture_ctrl
) {
521 free(p
->texture_ctrl
);
522 if (p
->texture_offsets
)
523 free(p
->texture_offsets
);
527 /* convert surfaces - geometry and possible attribute ones into equivalent */
528 /* sequence of adjacent Bezier patches */
530 convert_surfs(GLUnurbsObj
* nobj
, new_ctrl_type
* new_ctrl
)
532 knot_str_type geom_s_knot
, color_s_knot
, normal_s_knot
, texture_s_knot
;
533 knot_str_type geom_t_knot
, color_t_knot
, normal_t_knot
, texture_t_knot
;
536 if ((err
= fill_knot_structures(nobj
, &geom_s_knot
, &geom_t_knot
,
537 &color_s_knot
, &color_t_knot
,
538 &normal_s_knot
, &normal_t_knot
,
540 &texture_t_knot
)) != GLU_NO_ERROR
) {
543 /* unify knots - all knots should have the same working range */
544 if ((err
= select_knot_working_range(nobj
, &geom_s_knot
, &color_s_knot
,
546 &texture_s_knot
)) != GLU_NO_ERROR
) {
547 call_user_error(nobj
, err
);
550 if ((err
= select_knot_working_range(nobj
, &geom_t_knot
, &color_t_knot
,
552 &texture_t_knot
)) != GLU_NO_ERROR
) {
553 free_unified_knots(&geom_s_knot
, &color_s_knot
, &normal_s_knot
,
555 call_user_error(nobj
, err
);
559 /* convert the geometry surface */
560 nobj
->surface
.geom
.dim
= get_surface_dim(nobj
->surface
.geom
.type
);
561 if ((err
= convert_surf(&geom_s_knot
, &geom_t_knot
, &(nobj
->surface
.geom
),
562 &(new_ctrl
->geom_ctrl
), &(new_ctrl
->geom_s_pt_cnt
),
563 &(new_ctrl
->geom_t_pt_cnt
))) != GLU_NO_ERROR
) {
564 free_unified_knots(&geom_s_knot
, &color_s_knot
, &normal_s_knot
,
566 free_unified_knots(&geom_t_knot
, &color_t_knot
, &normal_t_knot
,
568 call_user_error(nobj
, err
);
571 /* if additional attributive surfaces are given convert them as well */
572 if (color_s_knot
.unified_knot
) {
573 nobj
->surface
.color
.dim
= get_surface_dim(nobj
->surface
.color
.type
);
576 convert_surf(&color_s_knot
, &color_t_knot
, &(nobj
->surface
.color
),
577 &(new_ctrl
->color_ctrl
), &(new_ctrl
->color_s_pt_cnt
),
578 &(new_ctrl
->color_t_pt_cnt
))) != GLU_NO_ERROR
) {
579 free_unified_knots(&color_s_knot
, &color_s_knot
, &normal_s_knot
,
581 free_unified_knots(&color_t_knot
, &color_t_knot
, &normal_t_knot
,
583 free_new_ctrl(new_ctrl
);
584 call_user_error(nobj
, err
);
588 if (normal_s_knot
.unified_knot
) {
589 nobj
->surface
.normal
.dim
= get_surface_dim(nobj
->surface
.normal
.type
);
590 if ((err
= convert_surf(&normal_s_knot
, &normal_t_knot
,
591 &(nobj
->surface
.normal
),
592 &(new_ctrl
->normal_ctrl
),
593 &(new_ctrl
->normal_s_pt_cnt
),
594 &(new_ctrl
->normal_t_pt_cnt
))) !=
596 free_unified_knots(&normal_s_knot
, &normal_s_knot
, &normal_s_knot
,
598 free_unified_knots(&normal_t_knot
, &normal_t_knot
, &normal_t_knot
,
600 free_new_ctrl(new_ctrl
);
601 call_user_error(nobj
, err
);
605 if (texture_s_knot
.unified_knot
) {
606 nobj
->surface
.texture
.dim
= get_surface_dim(nobj
->surface
.texture
.type
);
607 if ((err
= convert_surf(&texture_s_knot
, &texture_t_knot
,
608 &(nobj
->surface
.texture
),
609 &(new_ctrl
->texture_ctrl
),
610 &(new_ctrl
->texture_s_pt_cnt
),
611 &(new_ctrl
->texture_t_pt_cnt
))) !=
613 free_unified_knots(&texture_s_knot
, &texture_s_knot
, &texture_s_knot
,
615 free_unified_knots(&texture_t_knot
, &texture_t_knot
, &texture_t_knot
,
617 free_new_ctrl(new_ctrl
);
618 call_user_error(nobj
, err
);
625 /* tesselate the "boundary" Bezier edge strips */
627 tesselate_strip_t_line(GLint top_start
, GLint top_end
, GLint top_z
,
628 GLint bottom_start
, GLint bottom_end
, GLint bottom_z
,
631 GLint top_cnt
, bottom_cnt
, tri_cnt
, k
;
634 top_cnt
= top_end
- top_start
;
635 direction
= (top_cnt
>= 0 ? 1 : -1);
636 bottom_cnt
= bottom_end
- bottom_start
;
640 tri_cnt
= top_cnt
/ bottom_cnt
;
642 tri_cnt
= abs(top_cnt
);
643 for (k
= 0; k
<= tri_cnt
; k
++, top_start
+= direction
) {
644 glEvalCoord2f((GLfloat
) bottom_z
/ bottom_domain
,
645 (GLfloat
) bottom_start
/ bottom_domain
);
646 glEvalPoint2(top_z
, top_start
);
649 glEvalCoord2f((GLfloat
) bottom_z
/ bottom_domain
,
650 (GLfloat
) bottom_start
/ bottom_domain
);
651 bottom_start
+= direction
;
652 top_start
-= direction
;
653 glEvalCoord2f((GLfloat
) bottom_z
/ bottom_domain
,
654 (GLfloat
) bottom_start
/ bottom_domain
);
655 glEvalCoord2f((GLfloat
) bottom_z
/ bottom_domain
,
656 (GLfloat
) bottom_start
/ bottom_domain
);
657 glEvalPoint2(top_z
, top_start
);
659 top_cnt
-= direction
* tri_cnt
;
660 bottom_cnt
-= direction
;
667 tesselate_strip_t_fill(GLint top_start
, GLint top_end
, GLint top_z
,
668 GLint bottom_start
, GLint bottom_end
, GLint bottom_z
,
671 GLint top_cnt
, bottom_cnt
, tri_cnt
, k
;
674 top_cnt
= top_end
- top_start
;
675 direction
= (top_cnt
>= 0 ? 1 : -1);
676 bottom_cnt
= bottom_end
- bottom_start
;
679 tri_cnt
= top_cnt
/ bottom_cnt
;
681 tri_cnt
= abs(top_cnt
);
682 glBegin(GL_TRIANGLE_FAN
);
683 glEvalCoord2f((GLfloat
) bottom_z
/ bottom_domain
,
684 (GLfloat
) bottom_start
/ bottom_domain
);
685 for (k
= 0; k
<= tri_cnt
; k
++, top_start
+= direction
)
686 glEvalPoint2(top_z
, top_start
);
688 bottom_start
+= direction
;
689 top_start
-= direction
;
690 glEvalCoord2f((GLfloat
) bottom_z
/ bottom_domain
,
691 (GLfloat
) bottom_start
/ bottom_domain
);
694 top_cnt
-= direction
* tri_cnt
;
695 bottom_cnt
-= direction
;
701 tesselate_strip_t(GLenum display_mode
, GLint top_start
, GLint top_end
,
702 GLint top_z
, GLint bottom_start
, GLint bottom_end
,
703 GLint bottom_z
, GLint bottom_domain
)
705 if (display_mode
== GL_FILL
)
706 tesselate_strip_t_fill(top_start
, top_end
, top_z
, bottom_start
,
707 bottom_end
, bottom_z
, bottom_domain
);
709 tesselate_strip_t_line(top_start
, top_end
, top_z
, bottom_start
,
710 bottom_end
, bottom_z
, bottom_domain
);
715 tesselate_strip_s_fill(GLint top_start
, GLint top_end
, GLint top_z
,
716 GLint bottom_start
, GLint bottom_end
, GLint bottom_z
,
717 GLfloat bottom_domain
)
719 GLint top_cnt
, bottom_cnt
, tri_cnt
, k
;
722 top_cnt
= top_end
- top_start
;
723 direction
= (top_cnt
>= 0 ? 1 : -1);
724 bottom_cnt
= bottom_end
- bottom_start
;
727 tri_cnt
= top_cnt
/ bottom_cnt
;
729 tri_cnt
= abs(top_cnt
);
730 glBegin(GL_TRIANGLE_FAN
);
731 glEvalCoord2f((GLfloat
) bottom_start
/ bottom_domain
,
732 (GLfloat
) bottom_z
/ bottom_domain
);
733 for (k
= 0; k
<= tri_cnt
; k
++, top_start
+= direction
)
734 glEvalPoint2(top_start
, top_z
);
736 bottom_start
+= direction
;
737 top_start
-= direction
;
738 glEvalCoord2f((GLfloat
) bottom_start
/ bottom_domain
,
739 (GLfloat
) bottom_z
/ bottom_domain
);
742 top_cnt
-= direction
* tri_cnt
;
743 bottom_cnt
-= direction
;
749 tesselate_strip_s_line(GLint top_start
, GLint top_end
, GLint top_z
,
750 GLint bottom_start
, GLint bottom_end
, GLint bottom_z
,
751 GLfloat bottom_domain
)
753 GLint top_cnt
, bottom_cnt
, tri_cnt
, k
;
756 top_cnt
= top_end
- top_start
;
757 direction
= (top_cnt
>= 0 ? 1 : -1);
758 bottom_cnt
= bottom_end
- bottom_start
;
762 tri_cnt
= top_cnt
/ bottom_cnt
;
764 tri_cnt
= abs(top_cnt
);
765 for (k
= 0; k
<= tri_cnt
; k
++, top_start
+= direction
) {
766 glEvalCoord2f((GLfloat
) bottom_start
/ bottom_domain
,
767 (GLfloat
) bottom_z
/ bottom_domain
);
768 glEvalPoint2(top_start
, top_z
);
771 glEvalCoord2f((GLfloat
) bottom_start
/ bottom_domain
,
772 (GLfloat
) bottom_z
/ bottom_domain
);
773 bottom_start
+= direction
;
774 top_start
-= direction
;
775 glEvalCoord2f((GLfloat
) bottom_start
/ bottom_domain
,
776 (GLfloat
) bottom_z
/ bottom_domain
);
777 glEvalPoint2(top_start
, top_z
);
778 glEvalCoord2f((GLfloat
) bottom_start
/ bottom_domain
,
779 (GLfloat
) bottom_z
/ bottom_domain
);
781 top_cnt
-= direction
* tri_cnt
;
782 bottom_cnt
-= direction
;
789 tesselate_strip_s(GLenum display_mode
, GLint top_start
, GLint top_end
,
790 GLint top_z
, GLint bottom_start
, GLint bottom_end
,
791 GLint bottom_z
, GLfloat bottom_domain
)
793 if (display_mode
== GL_FILL
)
794 tesselate_strip_s_fill(top_start
, top_end
, top_z
, bottom_start
,
795 bottom_end
, bottom_z
, bottom_domain
);
797 tesselate_strip_s_line(top_start
, top_end
, top_z
, bottom_start
,
798 bottom_end
, bottom_z
, bottom_domain
);
802 tesselate_bottom_left_corner(GLenum display_mode
, GLfloat s_1
, GLfloat t_1
)
804 if (display_mode
== GL_FILL
) {
805 glBegin(GL_TRIANGLE_FAN
);
807 glEvalCoord2f(s_1
, 0.0);
808 glEvalCoord2f(0.0, 0.0);
809 glEvalCoord2f(0.0, t_1
);
813 glEvalCoord2f(0.0, 0.0);
814 glEvalCoord2f(0.0, t_1
);
815 glEvalCoord2f(0.0, 0.0);
817 glEvalCoord2f(0.0, 0.0);
818 glEvalCoord2f(s_1
, 0.0);
824 tesselate_bottom_right_corner(GLenum display_mode
, GLint v_top
,
825 GLint v_bottom
, GLfloat s_1
, GLfloat t_1
)
827 if (display_mode
== GL_FILL
) {
828 glBegin(GL_TRIANGLE_FAN
);
829 glEvalPoint2(1, v_top
);
830 glEvalCoord2f(0.0, v_bottom
* t_1
);
831 glEvalCoord2f(0.0, (v_bottom
+ 1) * t_1
);
832 glEvalCoord2f(s_1
, (v_bottom
+ 1) * t_1
);
836 glEvalCoord2f(0.0, (v_bottom
+ 1) * t_1
);
837 glEvalPoint2(1, v_top
);
838 glEvalCoord2f(0.0, (v_bottom
+ 1) * t_1
);
839 glEvalCoord2f(0.0, v_bottom
* t_1
);
840 glEvalCoord2f(0.0, (v_bottom
+ 1) * t_1
);
841 glEvalCoord2f(s_1
, (v_bottom
+ 1) * t_1
);
847 tesselate_top_left_corner(GLenum display_mode
, GLint u_right
, GLint u_left
,
848 GLfloat s_1
, GLfloat t_1
)
850 if (display_mode
== GL_FILL
) {
851 glBegin(GL_TRIANGLE_FAN
);
852 glEvalPoint2(u_right
, 1);
853 glEvalCoord2f((u_left
+ 1) * s_1
, t_1
);
854 glEvalCoord2f((u_left
+ 1) * s_1
, 0.0);
855 glEvalCoord2f(u_left
* s_1
, 0.0);
859 glEvalCoord2f((u_left
+ 1) * s_1
, 0.0);
860 glEvalPoint2(u_right
, 1);
861 glEvalCoord2f((u_left
+ 1) * s_1
, 0.0);
862 glEvalCoord2f(u_left
* s_1
, 0.0);
863 glEvalCoord2f((u_left
+ 1) * s_1
, 0.0);
864 glEvalCoord2f((u_left
+ 1) * s_1
, t_1
);
870 tesselate_top_right_corner(GLenum display_mode
, GLint u_left
, GLint v_bottom
,
871 GLint u_right
, GLint v_top
, GLfloat s_1
,
874 if (display_mode
== GL_FILL
) {
875 glBegin(GL_TRIANGLE_FAN
);
876 glEvalPoint2(u_left
, v_bottom
);
877 glEvalCoord2f((u_right
- 1) * s_1
, v_top
* t_1
);
878 glEvalCoord2f(u_right
* s_1
, v_top
* t_1
);
879 glEvalCoord2f(u_right
* s_1
, (v_top
- 1) * t_1
);
883 glEvalCoord2f(u_right
* s_1
, v_top
* t_1
);
884 glEvalPoint2(u_left
, v_bottom
);
885 glEvalCoord2f(u_right
* s_1
, v_top
* t_1
);
886 glEvalCoord2f(u_right
* s_1
, (v_top
- 1) * t_1
);
887 glEvalCoord2f(u_right
* s_1
, v_top
* t_1
);
888 glEvalCoord2f((u_right
- 1) * s_1
, v_top
* t_1
);
893 /* do mesh mapping of Bezier */
895 nurbs_map_bezier(GLenum display_mode
, GLint
* sfactors
, GLint
* tfactors
,
896 GLint s_bezier_cnt
, GLint t_bezier_cnt
, GLint s
, GLint t
)
898 GLint top
, bottom
, right
, left
;
902 top
= *(tfactors
+ t
* 3);
903 bottom
= *(tfactors
+ t
* 3 + 1);
905 else if (s
== s_bezier_cnt
- 1) {
906 top
= *(tfactors
+ t
* 3 + 2);
907 bottom
= *(tfactors
+ t
* 3);
910 top
= bottom
= *(tfactors
+ t
* 3);
913 left
= *(sfactors
+ s
* 3 + 1);
914 right
= *(sfactors
+ s
* 3);
916 else if (t
== t_bezier_cnt
- 1) {
917 left
= *(sfactors
+ s
* 3);
918 right
= *(sfactors
+ s
* 3 + 2);
921 left
= right
= *(sfactors
+ s
* 3);
926 glMapGrid2f(right
, 0.0, 1.0, top
, 0.0, 1.0);
927 glEvalMesh2(display_mode
, 1, right
, 1, top
);
928 tesselate_strip_s(display_mode
, 1, right
, 1, 1, left
, 0,
930 tesselate_bottom_left_corner(display_mode
, (GLfloat
) (1.0 / left
),
931 (GLfloat
) (1.0 / bottom
));
932 /* tesselate_strip_t(display_mode,1,top,1,1,bottom,0,(GLfloat)bottom);*/
933 tesselate_strip_t(display_mode
, top
, 1, 1, bottom
, 1, 0,
936 else if (left
== right
) {
937 glMapGrid2f(right
, 0.0, 1.0, top
, 0.0, 1.0);
938 glEvalMesh2(display_mode
, 1, right
, 0, top
);
939 /* tesselate_strip_t(display_mode,0,top,1,0,bottom,0,(GLfloat)bottom);*/
940 tesselate_strip_t(display_mode
, top
, 0, 1, bottom
, 0, 0,
944 glMapGrid2f(left
, 0.0, 1.0, top
, 0.0, 1.0);
945 glEvalMesh2(display_mode
, 1, left
, 0, top
- 1);
946 /* tesselate_strip_t(display_mode,0,top-1,1,0,bottom-1,0,
948 tesselate_strip_t(display_mode
, top
- 1, 0, 1, bottom
- 1, 0, 0,
950 tesselate_bottom_right_corner(display_mode
, top
- 1, bottom
- 1,
951 (GLfloat
) (1.0 / right
),
952 (GLfloat
) (1.0 / bottom
));
953 /* tesselate_strip_s(display_mode,1,left,top-1,1,right,right,
955 tesselate_strip_s(display_mode
, left
, 1, top
- 1, right
, 1, right
,
959 else if (top
== bottom
) {
961 glMapGrid2f(right
, 0.0, 1.0, top
, 0.0, 1.0);
962 glEvalMesh2(display_mode
, 0, right
, 1, top
);
963 tesselate_strip_s(display_mode
, 0, right
, 1, 0, left
, 0,
966 else if (left
== right
) {
967 glMapGrid2f(right
, 0.0, 1.0, top
, 0.0, 1.0);
968 glEvalMesh2(display_mode
, 0, right
, 0, top
);
971 glMapGrid2f(left
, 0.0, 1.0, top
, 0.0, 1.0);
972 glEvalMesh2(display_mode
, 0, left
, 0, top
- 1);
973 /* tesselate_strip_s(display_mode,0,left,top-1,0,right,right,
975 tesselate_strip_s(display_mode
, left
, 0, top
- 1, right
, 0, right
,
981 glMapGrid2f(right
, 0.0, 1.0, bottom
, 0.0, 1.0);
982 glEvalMesh2(display_mode
, 0, right
- 1, 1, bottom
);
983 tesselate_strip_s(display_mode
, 0, right
- 1, 1, 0, left
- 1, 0,
985 tesselate_top_left_corner(display_mode
, right
- 1, left
- 1,
986 (GLfloat
) (1.0 / left
),
987 (GLfloat
) (1.0 / top
));
988 tesselate_strip_t(display_mode
, 1, bottom
, right
- 1, 1, top
, top
,
991 else if (left
== right
) {
992 glMapGrid2f(right
, 0.0, 1.0, bottom
, 0.0, 1.0);
993 glEvalMesh2(display_mode
, 0, right
- 1, 0, bottom
);
994 tesselate_strip_t(display_mode
, 0, bottom
, right
- 1, 0, top
, top
,
998 glMapGrid2f(left
, 0.0, 1.0, bottom
, 0.0, 1.0);
999 glEvalMesh2(display_mode
, 0, left
- 1, 0, bottom
- 1);
1000 tesselate_strip_t(display_mode
, 0, bottom
- 1, left
- 1, 0, top
- 1,
1001 top
, (GLfloat
) top
);
1002 tesselate_top_right_corner(display_mode
, left
- 1, bottom
- 1, right
,
1003 top
, (GLfloat
) (1.0 / right
),
1004 (GLfloat
) (1.0 / top
));
1005 /* tesselate_strip_s(display_mode,0,left-1,bottom-1,0,right-1,right,
1007 tesselate_strip_s(display_mode
, left
- 1, 0, bottom
- 1, right
- 1,
1008 0, right
, (GLfloat
) right
);
1013 /* draw NURBS surface in OUTLINE POLYGON mode */
1015 draw_polygon_mode(GLenum display_mode
, GLUnurbsObj
* nobj
,
1016 new_ctrl_type
* new_ctrl
, GLint
* sfactors
,
1020 GLint t_bezier_cnt
, s_bezier_cnt
;
1021 GLboolean do_color
, do_normal
, do_texture
;
1024 t_bezier_cnt
= new_ctrl
->t_bezier_cnt
;
1025 s_bezier_cnt
= new_ctrl
->s_bezier_cnt
;
1026 glEnable(nobj
->surface
.geom
.type
);
1027 if (new_ctrl
->color_ctrl
) {
1028 glEnable(nobj
->surface
.color
.type
);
1032 do_color
= GL_FALSE
;
1033 if (new_ctrl
->normal_ctrl
) {
1034 glEnable(nobj
->surface
.normal
.type
);
1035 do_normal
= GL_TRUE
;
1038 do_normal
= GL_FALSE
;
1039 if (new_ctrl
->texture_ctrl
) {
1040 glEnable(nobj
->surface
.texture
.type
);
1041 do_texture
= GL_TRUE
;
1044 do_texture
= GL_FALSE
;
1045 for (j
= 0; j
< s_bezier_cnt
; j
++) {
1046 for (i
= 0; i
< t_bezier_cnt
; i
++) {
1047 offset
= j
* t_bezier_cnt
+ i
;
1048 if (fine_culling_test_3D(nobj
, *(new_ctrl
->geom_offsets
+ offset
),
1049 nobj
->surface
.geom
.sorder
,
1050 nobj
->surface
.geom
.torder
,
1051 new_ctrl
->geom_s_stride
,
1052 new_ctrl
->geom_t_stride
,
1053 nobj
->surface
.geom
.dim
)) continue;
1054 glMap2f(nobj
->surface
.geom
.type
, 0.0, 1.0, new_ctrl
->geom_s_stride
,
1055 nobj
->surface
.geom
.sorder
, 0.0, 1.0, new_ctrl
->geom_t_stride
,
1056 nobj
->surface
.geom
.torder
,
1057 *(new_ctrl
->geom_offsets
+ offset
));
1059 glMap2f(nobj
->surface
.color
.type
, 0.0, 1.0,
1060 new_ctrl
->color_s_stride
, nobj
->surface
.color
.sorder
,
1061 0.0, 1.0, new_ctrl
->color_t_stride
,
1062 nobj
->surface
.color
.torder
,
1063 *(new_ctrl
->color_offsets
+ offset
));
1066 glMap2f(nobj
->surface
.normal
.type
, 0.0, 1.0,
1067 new_ctrl
->normal_s_stride
, nobj
->surface
.normal
.sorder
,
1068 0.0, 1.0, new_ctrl
->normal_t_stride
,
1069 nobj
->surface
.normal
.torder
,
1070 *(new_ctrl
->normal_offsets
+ offset
));
1073 glMap2f(nobj
->surface
.texture
.type
, 0.0, 1.0,
1074 new_ctrl
->texture_s_stride
, nobj
->surface
.texture
.sorder
,
1075 0.0, 1.0, new_ctrl
->texture_t_stride
,
1076 nobj
->surface
.texture
.torder
,
1077 *(new_ctrl
->texture_offsets
+ offset
));
1079 /* glMapGrid2f(sfactors[j*3+0],0.0,1.0,tfactors[i*3+0],0.0,1.0);
1080 glEvalMesh2(display_mode,0,sfactors[j*3+0],0,tfactors[i*3+0]);*/
1081 nurbs_map_bezier(display_mode
, sfactors
, tfactors
, s_bezier_cnt
,
1082 t_bezier_cnt
, j
, i
);
1089 /* draw NURBS surface in OUTLINE POLYGON mode */
1092 draw_patch_mode(GLenum display_mode
, GLUnurbsObj
* nobj
,
1093 new_ctrl_type
* new_ctrl
, GLint
* sfactors
, GLint
* tfactors
)
1096 GLint t_bezier_cnt
, s_bezier_cnt
;
1097 GLboolean do_color
, do_normal
, do_texture
;
1100 t_bezier_cnt
= new_ctrl
->t_bezier_cnt
;
1101 s_bezier_cnt
= new_ctrl
->s_bezier_cnt
;
1102 glEnable(nobj
->surface
.geom
.type
);
1103 if (new_ctrl
->color_ctrl
) {
1104 glEnable(nobj
->surface
.color
.type
);
1108 do_color
= GL_FALSE
;
1109 if (new_ctrl
->normal_ctrl
) {
1110 glEnable(nobj
->surface
.normal
.type
);
1111 do_normal
= GL_TRUE
;
1114 do_normal
= GL_FALSE
;
1115 if (new_ctrl
->texture_ctrl
) {
1116 glEnable(nobj
->surface
.texture
.type
);
1117 do_texture
= GL_TRUE
;
1120 do_texture
= GL_FALSE
;
1121 for (j
= 0; j
< s_bezier_cnt
; j
++) {
1122 for (i
= 0; i
< t_bezier_cnt
; i
++) {
1123 offset
= j
* t_bezier_cnt
+ i
;
1124 if (fine_culling_test_3D(nobj
, *(new_ctrl
->geom_offsets
+ offset
),
1125 nobj
->surface
.geom
.sorder
,
1126 nobj
->surface
.geom
.torder
,
1127 new_ctrl
->geom_s_stride
,
1128 new_ctrl
->geom_t_stride
,
1129 nobj
->surface
.geom
.dim
)) continue;
1130 glMap2f(nobj
->surface
.geom
.type
, 0.0, 1.0, new_ctrl
->geom_s_stride
,
1131 nobj
->surface
.geom
.sorder
, 0.0, 1.0, new_ctrl
->geom_t_stride
,
1132 nobj
->surface
.geom
.torder
,
1133 *(new_ctrl
->geom_offsets
+ offset
));
1135 glMap2f(nobj
->surface
.color
.type
, 0.0, 1.0,
1136 new_ctrl
->color_s_stride
, nobj
->surface
.color
.sorder
,
1137 0.0, 1.0, new_ctrl
->color_t_stride
,
1138 nobj
->surface
.color
.torder
,
1139 *(new_ctrl
->color_offsets
+ offset
));
1142 glMap2f(nobj
->surface
.normal
.type
, 0.0, 1.0,
1143 new_ctrl
->normal_s_stride
, nobj
->surface
.normal
.sorder
,
1144 0.0, 1.0, new_ctrl
->normal_t_stride
,
1145 nobj
->surface
.normal
.torder
,
1146 *(new_ctrl
->normal_offsets
+ offset
));
1149 glMap2f(nobj
->surface
.texture
.type
, 0.0, 1.0,
1150 new_ctrl
->texture_s_stride
, nobj
->surface
.texture
.sorder
,
1151 0.0, 1.0, new_ctrl
->texture_t_stride
,
1152 nobj
->surface
.texture
.torder
,
1153 *(new_ctrl
->texture_offsets
+ offset
));
1155 nurbs_map_bezier(display_mode
, sfactors
, tfactors
, s_bezier_cnt
,
1156 t_bezier_cnt
, i
, j
);
1157 /* glMapGrid2f(sfactors[j],0.0,1.0,tfactors[i],0.0,1.0);
1158 glEvalMesh2(display_mode,0,sfactors[j],0,tfactors[i]);*/
1167 init_new_ctrl(new_ctrl_type
* p
)
1169 p
->geom_ctrl
= p
->color_ctrl
= p
->normal_ctrl
= p
->texture_ctrl
= NULL
;
1170 p
->geom_offsets
= p
->color_offsets
= p
->normal_offsets
=
1171 p
->texture_offsets
= NULL
;
1172 p
->s_bezier_cnt
= p
->t_bezier_cnt
= 0;
1177 augment_new_ctrl(GLUnurbsObj
* nobj
, new_ctrl_type
* p
)
1179 GLsizei offset_size
;
1182 p
->s_bezier_cnt
= (p
->geom_s_pt_cnt
) / (nobj
->surface
.geom
.sorder
);
1183 p
->t_bezier_cnt
= (p
->geom_t_pt_cnt
) / (nobj
->surface
.geom
.torder
);
1184 offset_size
= (p
->s_bezier_cnt
) * (p
->t_bezier_cnt
);
1185 p
->geom_t_stride
= nobj
->surface
.geom
.dim
;
1186 p
->geom_s_stride
= (p
->geom_t_pt_cnt
) * (nobj
->surface
.geom
.dim
);
1187 p
->color_t_stride
= nobj
->surface
.color
.dim
;
1188 p
->color_s_stride
= (p
->color_t_pt_cnt
) * (nobj
->surface
.color
.dim
);
1189 p
->normal_t_stride
= nobj
->surface
.normal
.dim
;
1190 p
->normal_s_stride
= (p
->normal_t_pt_cnt
) * (nobj
->surface
.normal
.dim
);
1191 p
->texture_t_stride
= nobj
->surface
.texture
.dim
;
1192 p
->texture_s_stride
= (p
->texture_t_pt_cnt
) * (nobj
->surface
.texture
.dim
);
1195 (GLfloat
**) malloc(sizeof(GLfloat
*) * offset_size
)) == NULL
) {
1196 call_user_error(nobj
, GLU_OUT_OF_MEMORY
);
1202 (GLfloat
**) malloc(sizeof(GLfloat
*) * offset_size
)) == NULL
) {
1204 call_user_error(nobj
, GLU_OUT_OF_MEMORY
);
1209 (p
->normal_offsets
=
1210 (GLfloat
**) malloc(sizeof(GLfloat
*) * offset_size
)) == NULL
) {
1212 call_user_error(nobj
, GLU_OUT_OF_MEMORY
);
1215 if (p
->texture_ctrl
)
1217 (p
->texture_offsets
=
1218 (GLfloat
**) malloc(sizeof(GLfloat
*) * offset_size
)) == NULL
) {
1220 call_user_error(nobj
, GLU_OUT_OF_MEMORY
);
1223 for (i
= 0; i
< p
->s_bezier_cnt
; i
++)
1224 for (j
= 0; j
< p
->t_bezier_cnt
; j
++)
1225 *(p
->geom_offsets
+ i
* (p
->t_bezier_cnt
) + j
) =
1226 p
->geom_ctrl
+ i
* (nobj
->surface
.geom
.sorder
) *
1227 (nobj
->surface
.geom
.dim
) * (p
->geom_t_pt_cnt
) +
1228 j
* (nobj
->surface
.geom
.dim
) * (nobj
->surface
.geom
.torder
);
1230 for (i
= 0; i
< p
->s_bezier_cnt
; i
++)
1231 for (j
= 0; j
< p
->t_bezier_cnt
; j
++)
1232 *(p
->color_offsets
+ i
* (p
->t_bezier_cnt
) + j
) =
1233 p
->color_ctrl
+ i
* (nobj
->surface
.color
.sorder
) *
1234 (nobj
->surface
.color
.dim
) * (p
->color_t_pt_cnt
) +
1235 j
* (nobj
->surface
.color
.dim
) * (nobj
->surface
.color
.torder
);
1237 for (i
= 0; i
< p
->s_bezier_cnt
; i
++)
1238 for (j
= 0; j
< p
->t_bezier_cnt
; j
++)
1239 *(p
->normal_offsets
+ i
* (p
->t_bezier_cnt
) + j
) =
1240 p
->normal_ctrl
+ i
* (nobj
->surface
.normal
.sorder
) *
1241 (nobj
->surface
.normal
.dim
) * (p
->normal_t_pt_cnt
) +
1242 j
* (nobj
->surface
.normal
.dim
) * (nobj
->surface
.normal
.torder
);
1243 if (p
->texture_ctrl
)
1244 for (i
= 0; i
< p
->s_bezier_cnt
; i
++)
1245 for (j
= 0; j
< p
->t_bezier_cnt
; j
++)
1246 *(p
->texture_offsets
+ i
* (p
->t_bezier_cnt
) + j
) =
1247 p
->texture_ctrl
+ i
* (nobj
->surface
.texture
.sorder
) *
1248 (nobj
->surface
.texture
.dim
) * (p
->texture_t_pt_cnt
) +
1249 j
* (nobj
->surface
.texture
.dim
) *
1250 (nobj
->surface
.texture
.torder
);
1251 return GLU_NO_ERROR
;
1254 /* main NURBS surface procedure */
1256 do_nurbs_surface(GLUnurbsObj
* nobj
)
1258 GLint
*sfactors
, *tfactors
;
1259 new_ctrl_type new_ctrl
;
1261 /* test user supplied data */
1262 if (test_nurbs_surfaces(nobj
) != GLU_NO_ERROR
)
1265 init_new_ctrl(&new_ctrl
);
1267 if (convert_surfs(nobj
, &new_ctrl
) != GLU_NO_ERROR
)
1269 if (augment_new_ctrl(nobj
, &new_ctrl
) != GLU_NO_ERROR
)
1271 switch (nobj
->sampling_method
) {
1272 case GLU_PATH_LENGTH
:
1273 if (glu_do_sampling_3D(nobj
, &new_ctrl
, &sfactors
, &tfactors
) !=
1275 free_new_ctrl(&new_ctrl
);
1279 case GLU_DOMAIN_DISTANCE
:
1280 if (glu_do_sampling_uv(nobj
, &new_ctrl
, &sfactors
, &tfactors
) !=
1282 free_new_ctrl(&new_ctrl
);
1286 case GLU_PARAMETRIC_ERROR
:
1287 if (glu_do_sampling_param_3D(nobj
, &new_ctrl
, &sfactors
, &tfactors
) !=
1289 free_new_ctrl(&new_ctrl
);
1297 switch (nobj
->display_mode
) {
1299 /* if(polygon_trimming(nobj,&new_ctrl,sfactors,tfactors)==GLU_NO_ERROR)*/
1300 draw_polygon_mode(GL_FILL
, nobj
, &new_ctrl
, sfactors
, tfactors
);
1302 case GLU_OUTLINE_POLYGON
:
1303 /* TODO - missing trimming handeling */
1304 /* just for now - no OUTLINE_PATCH mode
1305 draw_patch_mode(GL_LINE,nobj,&new_ctrl,sfactors,tfactors);
1307 case GLU_OUTLINE_PATCH
:
1308 /* if(polygon_trimming(nobj,&new_ctrl,sfactors,tfactors)==GLU_NO_ERROR)*/
1309 draw_polygon_mode(GL_LINE
, nobj
, &new_ctrl
, sfactors
, tfactors
);
1312 abort(); /* TODO: is this OK? */
1316 free_new_ctrl(&new_ctrl
);