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