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 <stdlib.h> 40 //#include <stdio.h> 41 #include <GL/gl.h> 42 #include "zlassert.h" 43 #include "gridWrap.h" 44 45 46 /*******************grid structure****************************/ 47 void gridWrap::print() 48 { 49 printf("n_ulines = %i\n", n_ulines); 50 printf("n_vlines = %i\n", n_vlines); 51 printf("u_min=%f, umax=%f, vmin=%f, vmax=%f\n", u_min, u_max, v_min, v_max); 52 } 53 54 gridWrap::gridWrap(Int nUlines, Real* uvals, 55 Int nVlines, Real* vvals) 56 { 57 assert(nUlines>=2); 58 assert(nVlines>=2); 59 60 is_uniform = 0; 61 n_ulines = nUlines; 62 n_vlines = nVlines; 63 u_min = uvals[0]; 64 u_max = uvals[nUlines-1]; 65 v_min = vvals[0]; 66 v_max = vvals[nVlines-1]; 67 u_values = (Real*) malloc(sizeof(Real) * n_ulines); 68 assert(u_values); 69 v_values = (Real*) malloc(sizeof(Real) * n_vlines); 70 assert(v_values); 71 72 Int i; 73 for(i=0; i<n_ulines; i++) 74 u_values[i] = uvals[i]; 75 for(i=0; i<n_vlines; i++) 76 v_values[i] = vvals[i]; 77 } 78 79 gridWrap::gridWrap(Int nUlines, Int nVlines, 80 Real uMin, Real uMax, 81 Real vMin, Real vMax 82 ) 83 { 84 is_uniform = 1; 85 n_ulines = nUlines; 86 n_vlines = nVlines; 87 u_min = uMin; 88 u_max = uMax; 89 v_min = vMin; 90 v_max = vMax; 91 u_values = (Real*) malloc(sizeof(Real) * n_ulines); 92 assert(u_values); 93 v_values = (Real*) malloc(sizeof(Real) * n_vlines); 94 assert(v_values); 95 96 Int i; 97 assert(nUlines>=2); 98 assert(nVlines>=2); 99 Real du = (uMax-uMin)/(nUlines-1); 100 Real dv = (vMax-vMin)/(nVlines-1); 101 102 float tempu=uMin; 103 u_values[0] = tempu; 104 for(i=1; i<nUlines; i++) 105 { 106 tempu += du; 107 u_values[i] = tempu; 108 } 109 u_values[nUlines-1] = uMax; 110 111 float tempv=vMin; 112 v_values[0] = tempv; 113 for(i=1; i<nVlines; i++) 114 { 115 tempv += dv; 116 v_values[i] = tempv; 117 } 118 v_values[nVlines-1] = vMax; 119 } 120 121 gridWrap::~gridWrap() 122 { 123 free(u_values); 124 free(v_values); 125 } 126 127 void gridWrap::draw() 128 { 129 int i,j; 130 glBegin(GL_POINTS); 131 for(i=0; i<n_ulines; i++) 132 for(j=0; j<n_vlines; j++) 133 glVertex2f(get_u_value(i), get_v_value(j)); 134 glEnd(); 135 } 136 137 void gridWrap::outputFanWithPoint(Int v, Int uleft, Int uright, Real vert[2], primStream* pStream) 138 { 139 Int i; 140 if(uleft >= uright) 141 return; //no triangles to output. 142 143 pStream->begin(); 144 pStream->insert(vert); 145 146 assert(vert[1] != v_values[v]); //don't output degenerate triangles 147 148 if(vert[1] > v_values[v]) //vertex is above this grid line: notice the orientation 149 { 150 for(i=uleft; i<=uright; i++) 151 pStream->insert(u_values[i], v_values[v]); 152 } 153 else //vertex is below the grid line 154 { 155 for(i=uright; i>= uleft; i--) 156 pStream->insert(u_values[i], v_values[v]); 157 } 158 159 pStream->end(PRIMITIVE_STREAM_FAN); 160 } 161 162 163 164 /*each chain stores a number of consecutive 165 *V-lines within a grid. 166 *There is one grid vertex on each V-line. 167 * The total number of V-lines is: 168 * nVlines. 169 * with respect to the grid, the index of the first V-line is 170 * firstVlineIndex. 171 * So with respect to the grid, the index of the ith V-line is 172 * firstVlineIndex-i. 173 * the grid-index of the uline at the ith vline (recall that each vline has one grid point) 174 * is ulineIndices[i]. The u_value is cached in ulineValues[i], that is, 175 * ulineValues[i] = grid->get_u_value(ulineIndices[i]) 176 */ 177 gridBoundaryChain::gridBoundaryChain( 178 gridWrap* gr, 179 Int first_vline_index, 180 Int n_vlines, 181 Int* uline_indices, 182 Int* inner_indices 183 ) 184 : grid(gr), firstVlineIndex(first_vline_index), nVlines(n_vlines) 185 { 186 ulineIndices = (Int*) malloc(sizeof(Int) * n_vlines); 187 assert(ulineIndices); 188 189 innerIndices = (Int*) malloc(sizeof(Int) * n_vlines); 190 assert(innerIndices); 191 192 vertices = (Real2*) malloc(sizeof(Real2) * n_vlines); 193 assert(vertices); 194 195 196 197 Int i; 198 for(i=0; i<n_vlines; i++){ 199 ulineIndices[i] = uline_indices[i]; 200 innerIndices[i] = inner_indices[i]; 201 } 202 203 for(i=0; i<n_vlines; i++){ 204 vertices[i][0] = gr->get_u_value(ulineIndices[i]); 205 vertices[i][1] = gr->get_v_value(first_vline_index-i); 206 } 207 } 208 209 void gridBoundaryChain::draw() 210 { 211 Int i; 212 glBegin(GL_LINE_STRIP); 213 for(i=0; i<nVlines; i++) 214 { 215 glVertex2fv(vertices[i]); 216 } 217 glEnd(); 218 } 219 220 void gridBoundaryChain::drawInner() 221 { 222 Int i; 223 for(i=1; i<nVlines; i++) 224 { 225 glBegin(GL_LINE_STRIP); 226 glVertex2f(grid->get_u_value(innerIndices[i]), get_v_value(i-1) ); 227 glVertex2f(grid->get_u_value(innerIndices[i]), get_v_value(i) ); 228 glEnd(); 229 } 230 } 231 232 Int gridBoundaryChain::lookfor(Real v, Int i1, Int i2) 233 { 234 Int mid; 235 while(i1 < i2-1) 236 { 237 mid = (i1+i2)/2; 238 if(v > vertices[mid][1]) 239 { 240 i2 = mid; 241 } 242 else 243 i1 = mid; 244 } 245 return i1; 246 } 247 248 /*output the fan of the right end between grid line i-1 and grid line i*/ 249 void gridBoundaryChain::rightEndFan(Int i, primStream* pStream) 250 { 251 Int j; 252 if(getUlineIndex(i) > getUlineIndex(i-1)) 253 { 254 pStream->begin(); 255 pStream->insert(get_vertex(i-1)); 256 for(j=getUlineIndex(i-1); j<= getUlineIndex(i); j++) 257 pStream->insert(grid->get_u_value(j), get_v_value(i)); 258 pStream->end(PRIMITIVE_STREAM_FAN); 259 } 260 else if(getUlineIndex(i) < getUlineIndex(i-1)) 261 { 262 pStream->begin(); 263 pStream->insert(get_vertex(i)); 264 for(j=getUlineIndex(i-1); j>= getUlineIndex(i); j--) 265 pStream->insert(grid->get_u_value(j), get_v_value(i-1)); 266 pStream->end(PRIMITIVE_STREAM_FAN); 267 } 268 //otherside, the two are equal, so there is no fan to output 269 } 270 271 272 /*output the fan of the left end between grid line i-1 and grid line i*/ 273 void gridBoundaryChain::leftEndFan(Int i, primStream* pStream) 274 { 275 Int j; 276 if(getUlineIndex(i) < getUlineIndex(i-1)) 277 { 278 pStream->begin(); 279 pStream->insert(get_vertex(i-1)); 280 for(j=getUlineIndex(i); j<= getUlineIndex(i-1); j++) 281 pStream->insert(grid->get_u_value(j), get_v_value(i)); 282 pStream->end(PRIMITIVE_STREAM_FAN); 283 } 284 else if(getUlineIndex(i) > getUlineIndex(i-1)) 285 { 286 pStream->begin(); 287 pStream->insert(get_vertex(i)); 288 for(j=getUlineIndex(i); j>= getUlineIndex(i-1); j--) 289 pStream->insert(grid->get_u_value(j), get_v_value(i-1)); 290 pStream->end(PRIMITIVE_STREAM_FAN); 291 } 292 /*otherwisem, the two are equal, so there is no fan to outout*/ 293 } 294