1f220fa62Smrg/*
2f220fa62Smrg** License Applicability. Except to the extent portions of this file are
3f220fa62Smrg** made subject to an alternative license as permitted in the SGI Free
4f220fa62Smrg** Software License B, Version 1.1 (the "License"), the contents of this
5f220fa62Smrg** file are subject only to the provisions of the License. You may not use
6f220fa62Smrg** this file except in compliance with the License. You may obtain a copy
7f220fa62Smrg** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
8f220fa62Smrg** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
9f220fa62Smrg**
10f220fa62Smrg** http://oss.sgi.com/projects/FreeB
11f220fa62Smrg**
12f220fa62Smrg** Note that, as provided in the License, the Software is distributed on an
13f220fa62Smrg** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
14f220fa62Smrg** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
15f220fa62Smrg** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
16f220fa62Smrg** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
17f220fa62Smrg**
18f220fa62Smrg** Original Code. The Original Code is: OpenGL Sample Implementation,
19f220fa62Smrg** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
20f220fa62Smrg** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
21f220fa62Smrg** Copyright in any portions created by third parties is as indicated
22f220fa62Smrg** elsewhere herein. All Rights Reserved.
23f220fa62Smrg**
24f220fa62Smrg** Additional Notice Provisions: The application programming interfaces
25f220fa62Smrg** established by SGI in conjunction with the Original Code are The
26f220fa62Smrg** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
27f220fa62Smrg** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
28f220fa62Smrg** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
29f220fa62Smrg** Window System(R) (Version 1.3), released October 19, 1998. This software
30f220fa62Smrg** was created using the OpenGL(R) version 1.2.1 Sample Implementation
31f220fa62Smrg** published by SGI, but has not been independently verified as being
32f220fa62Smrg** compliant with the OpenGL(R) version 1.2.1 Specification.
33f220fa62Smrg**
34f220fa62Smrg*/
35f220fa62Smrg/*
36f220fa62Smrg*/
37f220fa62Smrg
38f220fa62Smrg#include "gluos.h"
39f220fa62Smrg#include "glimports.h"
40f220fa62Smrg#include "glrenderer.h"
41f220fa62Smrg
42f220fa62SmrgGLUnurbs::GLUnurbs()
43f220fa62Smrg	: NurbsTessellator(curveEvaluator, surfaceEvaluator)
44f220fa62Smrg{
45f220fa62Smrg    redefineMaps();
46f220fa62Smrg    defineMap(GL_MAP2_NORMAL, 0, 3);
47f220fa62Smrg    defineMap(GL_MAP1_NORMAL, 0, 3);
48f220fa62Smrg    defineMap(GL_MAP2_TEXTURE_COORD_1, 0, 1);
49f220fa62Smrg    defineMap(GL_MAP1_TEXTURE_COORD_1, 0, 1);
50f220fa62Smrg    defineMap(GL_MAP2_TEXTURE_COORD_2, 0, 2);
51f220fa62Smrg    defineMap(GL_MAP1_TEXTURE_COORD_2, 0, 2);
52f220fa62Smrg    defineMap(GL_MAP2_TEXTURE_COORD_3, 0, 3);
53f220fa62Smrg    defineMap(GL_MAP1_TEXTURE_COORD_3, 0, 3);
54f220fa62Smrg    defineMap(GL_MAP2_TEXTURE_COORD_4, 1, 4);
55f220fa62Smrg    defineMap(GL_MAP1_TEXTURE_COORD_4, 1, 4);
56f220fa62Smrg    defineMap(GL_MAP2_VERTEX_4, 1, 4);
57f220fa62Smrg    defineMap(GL_MAP1_VERTEX_4, 1, 4);
58f220fa62Smrg    defineMap(GL_MAP2_VERTEX_3, 0, 3);
59f220fa62Smrg    defineMap(GL_MAP1_VERTEX_3, 0, 3);
60f220fa62Smrg    defineMap(GL_MAP2_COLOR_4, 0, 4);
61f220fa62Smrg    defineMap(GL_MAP1_COLOR_4, 0, 4);
62f220fa62Smrg    defineMap(GL_MAP2_INDEX, 0, 1);
63f220fa62Smrg    defineMap(GL_MAP1_INDEX, 0, 1);
64f220fa62Smrg
65f220fa62Smrg    setnurbsproperty(GL_MAP1_VERTEX_3, N_SAMPLINGMETHOD, (float) N_PATHLENGTH);
66f220fa62Smrg    setnurbsproperty(GL_MAP1_VERTEX_4, N_SAMPLINGMETHOD, (float) N_PATHLENGTH);
67f220fa62Smrg    setnurbsproperty(GL_MAP2_VERTEX_3, N_SAMPLINGMETHOD, (float) N_PATHLENGTH);
68f220fa62Smrg    setnurbsproperty(GL_MAP2_VERTEX_4, N_SAMPLINGMETHOD, (float) N_PATHLENGTH);
69f220fa62Smrg
70f220fa62Smrg    setnurbsproperty(GL_MAP1_VERTEX_3, N_PIXEL_TOLERANCE, (float) 50.0);
71f220fa62Smrg    setnurbsproperty(GL_MAP1_VERTEX_4, N_PIXEL_TOLERANCE, (float) 50.0);
72f220fa62Smrg    setnurbsproperty(GL_MAP2_VERTEX_3, N_PIXEL_TOLERANCE, (float) 50.0);
73f220fa62Smrg    setnurbsproperty(GL_MAP2_VERTEX_4, N_PIXEL_TOLERANCE, (float) 50.0);
74f220fa62Smrg
75f220fa62Smrg    setnurbsproperty(GL_MAP1_VERTEX_3, N_ERROR_TOLERANCE, (float) 0.50);
76f220fa62Smrg    setnurbsproperty(GL_MAP1_VERTEX_4, N_ERROR_TOLERANCE, (float) 0.50);
77f220fa62Smrg    setnurbsproperty(GL_MAP2_VERTEX_3, N_ERROR_TOLERANCE, (float) 0.50);
78f220fa62Smrg    setnurbsproperty(GL_MAP2_VERTEX_4, N_ERROR_TOLERANCE, (float) 0.50);
79f220fa62Smrg
80f220fa62Smrg    setnurbsproperty(GL_MAP1_VERTEX_3, N_S_STEPS, (float) 100.0);
81f220fa62Smrg    setnurbsproperty(GL_MAP1_VERTEX_4, N_S_STEPS, (float) 100.0);
82f220fa62Smrg    setnurbsproperty(GL_MAP2_VERTEX_3, N_S_STEPS, (float) 100.0);
83f220fa62Smrg    setnurbsproperty(GL_MAP2_VERTEX_4, N_S_STEPS, (float) 100.0);
84f220fa62Smrg
85f220fa62Smrg    //added for optimizing untrimmed case
86f220fa62Smrg    set_domain_distance_u_rate(100.0);
87f220fa62Smrg
88f220fa62Smrg    setnurbsproperty(GL_MAP1_VERTEX_3, N_T_STEPS, (float) 100.0);
89f220fa62Smrg    setnurbsproperty(GL_MAP1_VERTEX_4, N_T_STEPS, (float) 100.0);
90f220fa62Smrg    setnurbsproperty(GL_MAP2_VERTEX_3, N_T_STEPS, (float) 100.0);
91f220fa62Smrg    setnurbsproperty(GL_MAP2_VERTEX_4, N_T_STEPS, (float) 100.0);
92f220fa62Smrg
93f220fa62Smrg    //added for optimizing untrimmed case
94f220fa62Smrg    set_domain_distance_v_rate(100.0);
95f220fa62Smrg    set_is_domain_distance_sampling(0); //since the default is path_length
96f220fa62Smrg
97f220fa62Smrg    //default autoloadmode is true
98f220fa62Smrg    autoloadmode = 1;
99f220fa62Smrg
100f220fa62Smrg    //default callbackFlag is 0
101f220fa62Smrg    callbackFlag = 0;
102f220fa62Smrg
103f220fa62Smrg    errorCallback = NULL;
104f220fa62Smrg}
105f220fa62Smrg
106f220fa62Smrgvoid
107f220fa62SmrgGLUnurbs::bgnrender(void)
108f220fa62Smrg{
109f220fa62Smrg    if (autoloadmode) {
110f220fa62Smrg	loadGLMatrices();
111f220fa62Smrg    }
112f220fa62Smrg}
113f220fa62Smrg
114f220fa62Smrgvoid
115f220fa62SmrgGLUnurbs::endrender(void)
116f220fa62Smrg{
117f220fa62Smrg}
118f220fa62Smrg
119f220fa62Smrgvoid
120f220fa62SmrgGLUnurbs::errorHandler(int i)
121f220fa62Smrg{
122f220fa62Smrg    int gluError;
123f220fa62Smrg
124f220fa62Smrg    gluError = i + (GLU_NURBS_ERROR1 - 1);
125f220fa62Smrg    postError( gluError );
126f220fa62Smrg}
127f220fa62Smrg
128f220fa62Smrgvoid
129f220fa62SmrgGLUnurbs::loadGLMatrices(void)
130f220fa62Smrg{
131f220fa62Smrg    GLfloat vmat[4][4];
132f220fa62Smrg    GLint viewport[4];
133f220fa62Smrg
134f220fa62Smrg    grabGLMatrix((GLfloat (*)[4]) vmat);
135f220fa62Smrg    loadCullingMatrix((GLfloat (*)[4]) vmat);
136f220fa62Smrg    ::glGetIntegerv((GLenum) GL_VIEWPORT, (GLint *) viewport);
137f220fa62Smrg    loadSamplingMatrix((const GLfloat (*)[4]) vmat, (const GLint *) viewport);
138f220fa62Smrg}
139f220fa62Smrg
140f220fa62Smrgvoid
141f220fa62SmrgGLUnurbs::useGLMatrices(const GLfloat modelMatrix[16],
142f220fa62Smrg			  const GLfloat projMatrix[16],
143f220fa62Smrg			  const GLint viewport[4])
144f220fa62Smrg{
145f220fa62Smrg    GLfloat vmat[4][4];
146f220fa62Smrg
147f220fa62Smrg    multmatrix4d(vmat, (const GLfloat (*)[4]) modelMatrix,
148f220fa62Smrg	    (const GLfloat (*)[4]) projMatrix);
149f220fa62Smrg    loadCullingMatrix((GLfloat (*)[4]) vmat);
150f220fa62Smrg    loadSamplingMatrix((const GLfloat (*)[4]) vmat, (const GLint *) viewport);
151f220fa62Smrg}
152f220fa62Smrg
153f220fa62Smrg/*--------------------------------------------------------------------------
154f220fa62Smrg * grabGLMatrix
155f220fa62Smrg *--------------------------------------------------------------------------
156f220fa62Smrg */
157f220fa62Smrg
158f220fa62Smrgvoid
159f220fa62SmrgGLUnurbs::grabGLMatrix(GLfloat vmat[4][4])
160f220fa62Smrg{
161f220fa62Smrg    GLfloat m1[4][4], m2[4][4];
162f220fa62Smrg
163f220fa62Smrg    ::glGetFloatv((GLenum) GL_MODELVIEW_MATRIX, (GLfloat *) &(m1[0][0]));
164f220fa62Smrg    ::glGetFloatv((GLenum) GL_PROJECTION_MATRIX, (GLfloat *) &(m2[0][0]));
165f220fa62Smrg    multmatrix4d((GLfloat (*)[4]) vmat,
166f220fa62Smrg	    (const GLfloat (*)[4]) m1, (const GLfloat (*)[4]) m2);
167f220fa62Smrg}
168f220fa62Smrg
169f220fa62Smrg//for object space tesselation: view independent
170f220fa62Smrgvoid
171f220fa62SmrgGLUnurbs::setSamplingMatrixIdentity( void )
172f220fa62Smrg{
173f220fa62Smrg  INREAL smat[4][4] = {
174f220fa62Smrg    {1,0,0,0},
175f220fa62Smrg    {0,1,0,0},
176f220fa62Smrg    {0,0,1,0},
177f220fa62Smrg    {0,0,0,1}
178f220fa62Smrg  };
179f220fa62Smrg  const long rstride = sizeof(smat[0]) / sizeof(smat[0][0]);
180f220fa62Smrg  const long cstride = 1;
181f220fa62Smrg
182f220fa62Smrg  setnurbsproperty(GL_MAP1_VERTEX_3, N_SAMPLINGMATRIX, &smat[0][0], rstride,
183f220fa62Smrg		   cstride);
184f220fa62Smrg  setnurbsproperty(GL_MAP1_VERTEX_4, N_SAMPLINGMATRIX, &smat[0][0], rstride,
185f220fa62Smrg		   cstride);
186f220fa62Smrg  setnurbsproperty(GL_MAP2_VERTEX_3, N_SAMPLINGMATRIX, &smat[0][0], rstride,
187f220fa62Smrg		   cstride);
188f220fa62Smrg  setnurbsproperty(GL_MAP2_VERTEX_4, N_SAMPLINGMATRIX, &smat[0][0], rstride,
189f220fa62Smrg		   cstride);
190f220fa62Smrg}
191f220fa62Smrg
192f220fa62Smrg
193f220fa62Smrgvoid
194f220fa62SmrgGLUnurbs::loadSamplingMatrix(const GLfloat vmat[4][4],
195f220fa62Smrg			       const GLint viewport[4])
196f220fa62Smrg{
197f220fa62Smrg
198f220fa62Smrg    /* rescale the mapping to correspond to pixels in x/y */
199f220fa62Smrg    REAL xsize = 0.5 * (REAL) (viewport[2]);
200f220fa62Smrg    REAL ysize = 0.5 * (REAL) (viewport[3]);
201f220fa62Smrg
202f220fa62Smrg    INREAL smat[4][4];
203f220fa62Smrg    smat[0][0] = vmat[0][0] * xsize;
204f220fa62Smrg    smat[1][0] = vmat[1][0] * xsize;
205f220fa62Smrg    smat[2][0] = vmat[2][0] * xsize;
206f220fa62Smrg    smat[3][0] = vmat[3][0] * xsize;
207f220fa62Smrg
208f220fa62Smrg    smat[0][1] = vmat[0][1] * ysize;
209f220fa62Smrg    smat[1][1] = vmat[1][1] * ysize;
210f220fa62Smrg    smat[2][1] = vmat[2][1] * ysize;
211f220fa62Smrg    smat[3][1] = vmat[3][1] * ysize;
212f220fa62Smrg
213f220fa62Smrg    smat[0][2] = 0.0;
214f220fa62Smrg    smat[1][2] = 0.0;
215f220fa62Smrg    smat[2][2] = 0.0;
216f220fa62Smrg    smat[3][2] = 0.0;
217f220fa62Smrg
218f220fa62Smrg    smat[0][3] = vmat[0][3];
219f220fa62Smrg    smat[1][3] = vmat[1][3];
220f220fa62Smrg    smat[2][3] = vmat[2][3];
221f220fa62Smrg    smat[3][3] = vmat[3][3];
222f220fa62Smrg
223f220fa62Smrg    const long rstride = sizeof(smat[0]) / sizeof(smat[0][0]);
224f220fa62Smrg    const long cstride = 1;
225f220fa62Smrg
226f220fa62Smrg    setnurbsproperty(GL_MAP1_VERTEX_3, N_SAMPLINGMATRIX, &smat[0][0], rstride,
227f220fa62Smrg	    cstride);
228f220fa62Smrg    setnurbsproperty(GL_MAP1_VERTEX_4, N_SAMPLINGMATRIX, &smat[0][0], rstride,
229f220fa62Smrg	    cstride);
230f220fa62Smrg    setnurbsproperty(GL_MAP2_VERTEX_3, N_SAMPLINGMATRIX, &smat[0][0], rstride,
231f220fa62Smrg	    cstride);
232f220fa62Smrg    setnurbsproperty(GL_MAP2_VERTEX_4, N_SAMPLINGMATRIX, &smat[0][0], rstride,
233f220fa62Smrg	    cstride);
234f220fa62Smrg}
235f220fa62Smrg
236f220fa62Smrgvoid
237f220fa62SmrgGLUnurbs::loadCullingMatrix(GLfloat vmat[4][4])
238f220fa62Smrg{
239f220fa62Smrg    INREAL cmat[4][4];
240f220fa62Smrg
241f220fa62Smrg    cmat[0][0] = vmat[0][0];
242f220fa62Smrg    cmat[0][1] = vmat[0][1];
243f220fa62Smrg    cmat[0][2] = vmat[0][2];
244f220fa62Smrg    cmat[0][3] = vmat[0][3];
245f220fa62Smrg
246f220fa62Smrg    cmat[1][0] = vmat[1][0];
247f220fa62Smrg    cmat[1][1] = vmat[1][1];
248f220fa62Smrg    cmat[1][2] = vmat[1][2];
249f220fa62Smrg    cmat[1][3] = vmat[1][3];
250f220fa62Smrg
251f220fa62Smrg    cmat[2][0] = vmat[2][0];
252f220fa62Smrg    cmat[2][1] = vmat[2][1];
253f220fa62Smrg    cmat[2][2] = vmat[2][2];
254f220fa62Smrg    cmat[2][3] = vmat[2][3];
255f220fa62Smrg
256f220fa62Smrg    cmat[3][0] = vmat[3][0];
257f220fa62Smrg    cmat[3][1] = vmat[3][1];
258f220fa62Smrg    cmat[3][2] = vmat[3][2];
259f220fa62Smrg    cmat[3][3] = vmat[3][3];
260f220fa62Smrg
261f220fa62Smrg    const long rstride = sizeof(cmat[0]) / sizeof(cmat[0][0]);
262f220fa62Smrg    const long cstride = 1;
263f220fa62Smrg
264f220fa62Smrg    setnurbsproperty(GL_MAP2_VERTEX_3, N_CULLINGMATRIX, &cmat[0][0], rstride,
265f220fa62Smrg	    cstride);
266f220fa62Smrg    setnurbsproperty(GL_MAP2_VERTEX_4, N_CULLINGMATRIX, &cmat[0][0], rstride,
267f220fa62Smrg	    cstride);
268f220fa62Smrg	//added for curves by zl
269f220fa62Smrg    setnurbsproperty(GL_MAP1_VERTEX_3, N_CULLINGMATRIX, &cmat[0][0], rstride,
270f220fa62Smrg	    cstride);
271f220fa62Smrg    setnurbsproperty(GL_MAP1_VERTEX_4, N_CULLINGMATRIX, &cmat[0][0], rstride,
272f220fa62Smrg	    cstride);
273f220fa62Smrg}
274f220fa62Smrg
275f220fa62Smrg/*---------------------------------------------------------------------
276f220fa62Smrg * A = B * MAT ; transform a 4d vector through a 4x4 matrix
277f220fa62Smrg *---------------------------------------------------------------------
278f220fa62Smrg */
279f220fa62Smrgvoid
280f220fa62SmrgGLUnurbs::transform4d(GLfloat A[4], GLfloat B[4], GLfloat mat[4][4])
281f220fa62Smrg{
282f220fa62Smrg
283f220fa62Smrg    A[0] = B[0]*mat[0][0] + B[1]*mat[1][0] + B[2]*mat[2][0] + B[3]*mat[3][0];
284f220fa62Smrg    A[1] = B[0]*mat[0][1] + B[1]*mat[1][1] + B[2]*mat[2][1] + B[3]*mat[3][1];
285f220fa62Smrg    A[2] = B[0]*mat[0][2] + B[1]*mat[1][2] + B[2]*mat[2][2] + B[3]*mat[3][2];
286f220fa62Smrg    A[3] = B[0]*mat[0][3] + B[1]*mat[1][3] + B[2]*mat[2][3] + B[3]*mat[3][3];
287f220fa62Smrg}
288f220fa62Smrg
289f220fa62Smrg/*---------------------------------------------------------------------
290f220fa62Smrg * new = [left][right] ; multiply two matrices together
291f220fa62Smrg *---------------------------------------------------------------------
292f220fa62Smrg */
293f220fa62Smrgvoid
294f220fa62SmrgGLUnurbs::multmatrix4d (GLfloat n[4][4], const GLfloat left[4][4],
295f220fa62Smrg		 const GLfloat right[4][4])
296f220fa62Smrg{
297f220fa62Smrg    transform4d ((GLfloat *) n[0],(GLfloat *) left[0],(GLfloat (*)[4]) right);
298f220fa62Smrg    transform4d ((GLfloat *) n[1],(GLfloat *) left[1],(GLfloat (*)[4]) right);
299f220fa62Smrg    transform4d ((GLfloat *) n[2],(GLfloat *) left[2],(GLfloat (*)[4]) right);
300f220fa62Smrg    transform4d ((GLfloat *) n[3],(GLfloat *) left[3],(GLfloat (*)[4]) right);
301f220fa62Smrg}
302