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****************************/ 47void 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 54gridWrap::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 79gridWrap::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 121gridWrap::~gridWrap() 122{ 123 free(u_values); 124 free(v_values); 125} 126 127void 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 137void 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 */ 177gridBoundaryChain::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 209void 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 220void 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 232Int 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*/ 249void 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*/ 273void 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