📄 glsurfeval.cc
字号:
/*** License Applicability. Except to the extent portions of this file are** made subject to an alternative license as permitted in the SGI Free** Software License B, Version 1.1 (the "License"), the contents of this** file are subject only to the provisions of the License. You may not use** this file except in compliance with the License. You may obtain a copy** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:**** http://oss.sgi.com/projects/FreeB**** Note that, as provided in the License, the Software is distributed on an** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.**** Original Code. The Original Code is: OpenGL Sample Implementation,** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.** Copyright in any portions created by third parties is as indicated** elsewhere herein. All Rights Reserved.**** Additional Notice Provisions: The application programming interfaces** established by SGI in conjunction with the Original Code are The** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X** Window System(R) (Version 1.3), released October 19, 1998. This software** was created using the OpenGL(R) version 1.2.1 Sample Implementation** published by SGI, but has not been independently verified as being** compliant with the OpenGL(R) version 1.2.1 Specification.*//* * glsurfeval.c++ * *//* Polynomial Evaluator Interface */#include "gluos.h"#include <stdio.h>#include "glimports.h"#include "glrenderer.h"#include "glsurfeval.h"#include "nurbsconsts.h"#include "bezierPatchMesh.h"//extern int surfcount;//int surfcount=0;/*#define USE_INTERNAL_EVAL*/ //use internal evaluator/*whether do evaluation or not*//*#define NO_EVALUATION*///#define USE_LOD //for LOD test, have to turn on USE_LOD in insurfeval.c++ too/*for statistics*///#define STATISTICS#ifdef STATISTICSstatic int STAT_num_of_triangles=0;static int STAT_num_of_eval_vertices=0;static int STAT_num_of_quad_strips=0;#endif/*for output triangles*//*#define OUTPUT_TRIANGLES*//*#define FOR_CHRIS*/#ifdef FOR_CHRISextern "C" { void evalUStripExt(int n_upper, REAL v_upper, REAL* upper_val, int n_lower, REAL v_lower, REAL* lower_val);}extern "C" { void evalVStripExt(int n_left, REAL u_left, REAL* left_val, int n_right, REAL u_right, REAL* right_val); }#endif/**************begin for LOD_eval_list***********/void OpenGLSurfaceEvaluator::LOD_eval_list(int level){ if(level == 0) LOD_eval_level = 1; else if(level == 1) LOD_eval_level = 2; else if(level == 2) LOD_eval_level = 4; else LOD_eval_level = 8; inBPMListEvalEM(global_bpm);}OpenGLSurfaceEvaluator::OpenGLSurfaceEvaluator(){ int i; for (i=0; i<VERTEX_CACHE_SIZE; i++) { vertexCache[i] = new StoredVertex; } tmeshing = 0; which = 0; vcount = 0; global_uorder = 0; global_vorder = 0; global_uprime = -1.0; global_vprime = -1.0; global_vprime_BV = -1.0; global_uprime_BU = -1.0; global_uorder_BU = 0; global_vorder_BU = 0; global_uorder_BV = 0; global_vorder_BV = 0; global_baseData = NULL; global_bpm = NULL; output_triangles = 0; //don't output triangles by default //no default callback functions beginCallBackN = NULL; endCallBackN = NULL; vertexCallBackN = NULL; normalCallBackN = NULL; colorCallBackN = NULL; texcoordCallBackN = NULL; beginCallBackData = NULL; endCallBackData = NULL; vertexCallBackData = NULL; normalCallBackData = NULL; colorCallBackData = NULL; texcoordCallBackData = NULL; userData = NULL; auto_normal_flag = 0; callback_auto_normal = 0; //default of GLU_CALLBACK_AUTO_NORMAL is 0 vertex_flag = 0; normal_flag = 0; color_flag = 0; texcoord_flag = 0; em_vertex.uprime = -1.0; em_vertex.vprime = -1.0; em_normal.uprime = -1.0; em_normal.vprime = -1.0; em_color.uprime = -1.0; em_color.vprime = -1.0; em_texcoord.uprime = -1.0; em_texcoord.vprime = -1.0;#ifdef USE_LOD LOD_eval_level = 1;#endif}OpenGLSurfaceEvaluator::~OpenGLSurfaceEvaluator(){ for (int ii= 0; ii< VERTEX_CACHE_SIZE; ii++) { delete vertexCache[ii]; vertexCache[ii]= 0; }}/*--------------------------------------------------------------------------- * disable - turn off a map *--------------------------------------------------------------------------- */voidOpenGLSurfaceEvaluator::disable(long type){ glDisable((GLenum) type);}/*--------------------------------------------------------------------------- * enable - turn on a map *--------------------------------------------------------------------------- */voidOpenGLSurfaceEvaluator::enable(long type){ glEnable((GLenum) type);}/*------------------------------------------------------------------------- * mapgrid2f - define a lattice of points with origin and offset *------------------------------------------------------------------------- */voidOpenGLSurfaceEvaluator::mapgrid2f(long nu, REAL u0, REAL u1, long nv, REAL v0, REAL v1){#ifdef USE_INTERNAL_EVAL inMapGrid2f((int) nu, (REAL) u0, (REAL) u1, (int) nv, (REAL) v0, (REAL) v1);#else if(output_triangles) { global_grid_u0 = u0; global_grid_u1 = u1; global_grid_nu = nu; global_grid_v0 = v0; global_grid_v1 = v1; global_grid_nv = nv; } else glMapGrid2d((GLint) nu, (GLdouble) u0, (GLdouble) u1, (GLint) nv, (GLdouble) v0, (GLdouble) v1);#endif}voidOpenGLSurfaceEvaluator::polymode(long style){ if(! output_triangles) { switch(style) { default: case N_MESHFILL: glPolygonMode((GLenum) GL_FRONT_AND_BACK, (GLenum) GL_FILL); break; case N_MESHLINE: glPolygonMode((GLenum) GL_FRONT_AND_BACK, (GLenum) GL_LINE); break; case N_MESHPOINT: glPolygonMode((GLenum) GL_FRONT_AND_BACK, (GLenum) GL_POINT); break; } }}voidOpenGLSurfaceEvaluator::bgnline(void){ if(output_triangles) bezierPatchMeshBeginStrip(global_bpm, GL_LINE_STRIP); else glBegin((GLenum) GL_LINE_STRIP);}voidOpenGLSurfaceEvaluator::endline(void){ if(output_triangles) bezierPatchMeshEndStrip(global_bpm); else glEnd();}voidOpenGLSurfaceEvaluator::range2f(long type, REAL *from, REAL *to){}voidOpenGLSurfaceEvaluator::domain2f(REAL ulo, REAL uhi, REAL vlo, REAL vhi){}voidOpenGLSurfaceEvaluator::bgnclosedline(void){ if(output_triangles) bezierPatchMeshBeginStrip(global_bpm, GL_LINE_LOOP); else glBegin((GLenum) GL_LINE_LOOP);}voidOpenGLSurfaceEvaluator::endclosedline(void){ if(output_triangles) bezierPatchMeshEndStrip(global_bpm); else glEnd();}voidOpenGLSurfaceEvaluator::bgntmesh(void){ tmeshing = 1; which = 0; vcount = 0; if(output_triangles) bezierPatchMeshBeginStrip(global_bpm, GL_TRIANGLES); else glBegin((GLenum) GL_TRIANGLES);}voidOpenGLSurfaceEvaluator::swaptmesh(void){ which = 1 - which;}voidOpenGLSurfaceEvaluator::endtmesh(void){ tmeshing = 0; if(output_triangles) bezierPatchMeshEndStrip(global_bpm); else glEnd();}voidOpenGLSurfaceEvaluator::bgntfan(void){ if(output_triangles) bezierPatchMeshBeginStrip(global_bpm, GL_TRIANGLE_FAN); else glBegin((GLenum) GL_TRIANGLE_FAN);}voidOpenGLSurfaceEvaluator::endtfan(void){ if(output_triangles) bezierPatchMeshEndStrip(global_bpm); else glEnd();}voidOpenGLSurfaceEvaluator::evalUStrip(int n_upper, REAL v_upper, REAL* upper_val, int n_lower, REAL v_lower, REAL* lower_val){#ifdef USE_INTERNAL_EVAL inEvalUStrip(n_upper, v_upper, upper_val, n_lower, v_lower, lower_val);#else#ifdef FOR_CHRIS evalUStripExt(n_upper, v_upper, upper_val, n_lower, v_lower, lower_val); return;#endif int i,j,k,l; REAL leftMostV[2]; /* *the algorithm works by scanning from left to right. *leftMostV: the left most of the remaining verteces (on both upper and lower). * it could an element of upperVerts or lowerVerts. *i: upperVerts[i] is the first vertex to the right of leftMostV on upper line *j: lowerVerts[j] is the first vertex to the right of leftMostV on lower line */ /*initialize i,j,and leftMostV */ if(upper_val[0] <= lower_val[0]) { i=1; j=0; leftMostV[0] = upper_val[0]; leftMostV[1] = v_upper; } else { i=0; j=1; leftMostV[0] = lower_val[0]; leftMostV[1] = v_lower; } /*the main loop. *the invariance is that: *at the beginning of each loop, the meaning of i,j,and leftMostV are *maintained */ while(1) { if(i >= n_upper) /*case1: no more in upper*/ { if(j<n_lower-1) /*at least two vertices in lower*/ { bgntfan(); coord2f(leftMostV[0], leftMostV[1]);// glNormal3fv(leftMostNormal);// glVertex3fv(leftMostXYZ); while(j<n_lower){ coord2f(lower_val[j], v_lower);// glNormal3fv(lowerNormal[j]);// glVertex3fv(lowerXYZ[j]); j++; } endtfan(); } break; /*exit the main loop*/ } else if(j>= n_lower) /*case2: no more in lower*/ { if(i<n_upper-1) /*at least two vertices in upper*/ { bgntfan(); coord2f(leftMostV[0], leftMostV[1]);// glNormal3fv(leftMostNormal);// glVertex3fv(leftMostXYZ); for(k=n_upper-1; k>=i; k--) /*reverse order for two-side lighting*/ { coord2f(upper_val[k], v_upper);// glNormal3fv(upperNormal[k]);// glVertex3fv(upperXYZ[k]); } endtfan(); } break; /*exit the main loop*/ } else /* case3: neither is empty, plus the leftMostV, there is at least one triangle to output*/ { if(upper_val[i] <= lower_val[j]) { bgntfan(); coord2f(lower_val[j], v_lower);// glNormal3fv(lowerNormal[j]);// glVertex3fv(lowerXYZ[j]); /*find the last k>=i such that *upperverts[k][0] <= lowerverts[j][0] */ k=i; while(k<n_upper) { if(upper_val[k] > lower_val[j]) break; k++; } k--; for(l=k; l>=i; l--)/*the reverse is for two-side lighting*/ { coord2f(upper_val[l], v_upper);// glNormal3fv(upperNormal[l]);// glVertex3fv(upperXYZ[l]); } coord2f(leftMostV[0], leftMostV[1]);// glNormal3fv(leftMostNormal);// glVertex3fv(leftMostXYZ); endtfan(); /*update i and leftMostV for next loop */ i = k+1; leftMostV[0] = upper_val[k]; leftMostV[1] = v_upper;// leftMostNormal = upperNormal[k];// leftMostXYZ = upperXYZ[k]; } else /*upperVerts[i][0] > lowerVerts[j][0]*/ { bgntfan(); coord2f(upper_val[i], v_upper);// glNormal3fv(upperNormal[i]);// glVertex3fv(upperXYZ[i]); coord2f(leftMostV[0], leftMostV[1]);// glNormal3fv(leftMostNormal);// glVertex3fv(leftMostXYZ); /*find the last k>=j such that *lowerverts[k][0] < upperverts[i][0] */ k=j; while(k< n_lower) { if(lower_val[k] >= upper_val[i]) break; coord2f(lower_val[k], v_lower);// glNormal3fv(lowerNormal[k]);// glVertex3fv(lowerXYZ[k]); k++; } endtfan(); /*update j and leftMostV for next loop */ j=k; leftMostV[0] = lower_val[j-1]; leftMostV[1] = v_lower;// leftMostNormal = lowerNormal[j-1];// leftMostXYZ = lowerXYZ[j-1]; } } } //clean up// free(upperXYZ);// free(lowerXYZ);// free(upperNormal);// free(lowerNormal);#endif}voidOpenGLSurfaceEvaluator::evalVStrip(int n_left, REAL u_left, REAL* left_val, int n_right, REAL u_right, REAL* right_val){#ifdef USE_INTERNAL_EVAL inEvalVStrip(n_left, u_left, left_val, n_right, u_right, right_val);#else#ifdef FOR_CHRIS evalVStripExt(n_left, u_left, left_val, n_right, u_right, right_val); return;#endif int i,j,k,l; REAL botMostV[2]; /* *the algorithm works by scanning from bot to top. *botMostV: the bot most of the remaining verteces (on both left and right). * it could an element of leftVerts or rightVerts. *i: leftVerts[i] is the first vertex to the top of botMostV on left line *j: rightVerts[j] is the first vertex to the top of botMostV on rightline */ /*initialize i,j,and botMostV */ if(left_val[0] <= right_val[0]) { i=1; j=0; botMostV[0] = u_left; botMostV[1] = left_val[0]; } else { i=0; j=1; botMostV[0] = u_right; botMostV[1] = right_val[0]; } /*the main loop. *the invariance is that: *at the beginning of each loop, the meaning of i,j,and botMostV are *maintained */ while(1) { if(i >= n_left) /*case1: no more in left*/ { if(j<n_right-1) /*at least two vertices in right*/ { bgntfan(); coord2f(botMostV[0], botMostV[1]); while(j<n_right){ coord2f(u_right, right_val[j]);// glNormal3fv(rightNormal[j]);// glVertex3fv(rightXYZ[j]); j++; } endtfan(); } break; /*exit the main loop*/ } else if(j>= n_right) /*case2: no more in right*/ { if(i<n_left-1) /*at least two vertices in left*/ { bgntfan(); coord2f(botMostV[0], botMostV[1]);// glNormal3fv(botMostNormal);// glVertex3fv(botMostXYZ); for(k=n_left-1; k>=i; k--) /*reverse order for two-side lighting*/ { coord2f(u_left, left_val[k]);// glNormal3fv(leftNormal[k]);// glVertex3fv(leftXYZ[k]); } endtfan(); } break; /*exit the main loop*/ } else /* case3: neither is empty, plus the botMostV, there is at least one triangle to output*/ { if(left_val[i] <= right_val[j]) { bgntfan(); coord2f(u_right, right_val[j]);// glNormal3fv(rightNormal[j]);// glVertex3fv(rightXYZ[j]); /*find the last k>=i such that *leftverts[k][0] <= rightverts[j][0] */ k=i; while(k<n_left) { if(left_val[k] > right_val[j]) break; k++; } k--; for(l=k; l>=i; l--)/*the reverse is for two-side lighting*/ { coord2f(u_left, left_val[l]);// glNormal3fv(leftNormal[l]);// glVertex3fv(leftXYZ[l]); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -