📄 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 STATISTICS
static 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_CHRIS
extern "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
*---------------------------------------------------------------------------
*/
void
OpenGLSurfaceEvaluator::disable(long type)
{
glDisable((GLenum) type);
}
/*---------------------------------------------------------------------------
* enable - turn on a map
*---------------------------------------------------------------------------
*/
void
OpenGLSurfaceEvaluator::enable(long type)
{
glEnable((GLenum) type);
}
/*-------------------------------------------------------------------------
* mapgrid2f - define a lattice of points with origin and offset
*-------------------------------------------------------------------------
*/
void
OpenGLSurfaceEvaluator::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
}
void
OpenGLSurfaceEvaluator::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;
}
}
}
void
OpenGLSurfaceEvaluator::bgnline(void)
{
if(output_triangles)
bezierPatchMeshBeginStrip(global_bpm, GL_LINE_STRIP);
else
glBegin((GLenum) GL_LINE_STRIP);
}
void
OpenGLSurfaceEvaluator::endline(void)
{
if(output_triangles)
bezierPatchMeshEndStrip(global_bpm);
else
glEnd();
}
void
OpenGLSurfaceEvaluator::range2f(long type, REAL *from, REAL *to)
{
}
void
OpenGLSurfaceEvaluator::domain2f(REAL ulo, REAL uhi, REAL vlo, REAL vhi)
{
}
void
OpenGLSurfaceEvaluator::bgnclosedline(void)
{
if(output_triangles)
bezierPatchMeshBeginStrip(global_bpm, GL_LINE_LOOP);
else
glBegin((GLenum) GL_LINE_LOOP);
}
void
OpenGLSurfaceEvaluator::endclosedline(void)
{
if(output_triangles)
bezierPatchMeshEndStrip(global_bpm);
else
glEnd();
}
void
OpenGLSurfaceEvaluator::bgntmesh(void)
{
tmeshing = 1;
which = 0;
vcount = 0;
if(output_triangles)
bezierPatchMeshBeginStrip(global_bpm, GL_TRIANGLES);
else
glBegin((GLenum) GL_TRIANGLES);
}
void
OpenGLSurfaceEvaluator::swaptmesh(void)
{
which = 1 - which;
}
void
OpenGLSurfaceEvaluator::endtmesh(void)
{
tmeshing = 0;
if(output_triangles)
bezierPatchMeshEndStrip(global_bpm);
else
glEnd();
}
void
OpenGLSurfaceEvaluator::bgntfan(void)
{
if(output_triangles)
bezierPatchMeshBeginStrip(global_bpm, GL_TRIANGLE_FAN);
else
glBegin((GLenum) GL_TRIANGLE_FAN);
}
void
OpenGLSurfaceEvaluator::endtfan(void)
{
if(output_triangles)
bezierPatchMeshEndStrip(global_bpm);
else
glEnd();
}
void
OpenGLSurfaceEvaluator::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();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -