# OPENGL(14) c++曲面构造 网格线

1.曲面定义
void glMap2{fd}(GLenum target,TYPE u1,TYPE u2,GLint ustride,GLint uorder,
TYPE v1,TYPE v2,GLint vstride,GLint vorder,TYPE points);
target的定义同上次介绍的曲线中target的定义。
U V是二维曲面坐标
uorder,vorder;ustride,vstride的定义都类似曲线定义。
points是控制点坐标

2.曲面任意一点的计算
void glEvalCoord2{fd}[v](TYPE u,TYPE v);

3.曲面绘制的控制
void glMapGrid2{fd}(GLenum nu,TYPE u1,TYPE u2,GLenum nv,TYPE v1,TYPE v2);

////////////////////////////////////////////////////////////
//sample.cpp
#include "glos.h"
#include
#include
#include "windows.h"
void myinit(void);
void CALLBACK display(void);
void CALLBACK reshape(GLsizei w,GLsizei h);

//控制点坐标
GLfloat points[4][4][3]={
{{-1.5,-1.5,2.0},{-0.5,-1.5,2.0},
{0.5,-1.5,-1.0},{1.5,-1.5,2.0}},
{{-1.5,-0.5,1.0},{-0.5,1.5,2.0},
{0.5,0.5,1.0},{1.5,-0.5,-1.0}},
{{-1.5,0.5,2.0},{-0.5,0.5,1.0},
{0.5,0.5,3.0},{1.5,-1.5,1.5}},
{{-1.5,1.5,-2.0},{-0.5,1.5,-2.0},
{0.5,0.5,1.0},{1.5,1.5,-1.0}}};

//为了清楚显示控制点而设置的一组颜色
GLfloat color[4][3]={
{1.0,0.0,0.0},{0.0,1.0,0.0},{0.0,0.0,1.0},{1.0,1.0,1.0}};

void myinit(void)
{

auxInitDisplayMode(AUX_SINGLE|AUX_RGBA);
auxInitPosition(0,0,500,500);
auxInitWindow("sample1");
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);

//利用glEnable()来启用曲面模式
glMap2f(GL_MAP2_VERTEX_3,0,1,3,4,0,1,12,4,&points[0][0][0]);
glEnable(GL_MAP2_VERTEX_3);

glMapGrid2f(20,0.0,1.0,20,0.0,1.0);

glEnable(GL_DEPTH_TEST);
}

void CALLBACK reshape(GLsizei w,GLsizei h)
{

glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);

if(w<=h)
glOrtho(-5.0,5.0,-5.0*(GLfloat)h/(GLfloat)w,
5.0*(GLfloat)h/(GLfloat)w,-5.0,5.0);
else
glOrtho(-5.0*(GLfloat)h/(GLfloat)w,
5.0*(GLfloat)h/(GLfloat)w,-5.0,5.0,-5.0,5.0);
glMatrixMode(GL_MODELVIEW);
}

void CALLBACK display(void)
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glColor3f(0.0,0.0,1.0);
glPushMatrix();
glRotatef(35.0,1.0,1.0,1.0);
//用直线段的连接描绘曲面结构
glBegin(GL_LINE_STRIP);
int i,j;
//在U V方向各画出8条网格线，用以构造曲面结构
for(j=0;j<=8;j++)
{
//在U方向用30条直线段描绘一条曲线
glBegin(GL_LINE_STRIP);
for(i=0;i<=30;i++)
glEvalCoord2f((GLfloat)i/30.0,(GLfloat)j/8.0);
glEnd();

//在V方向用30条直线段描绘一条曲线
glBegin(GL_LINE_STRIP);
for(i=0;i<=30;i++)
glEvalCoord2f((GLfloat)j/8.0,(GLfloat)i/30.0);
glEnd();
}

//用不同的颜色把控制点显示出来
glPointSize(4.0);
glBegin(GL_POINTS);
for(i=0;i<4;i++)
for(j=0;j<4;j++)
{
glColor3fv(color[i]);
glVertex3fv(&points[i][j][0]);
}
glEnd();

glPopMatrix();
glFlush();
}
void main(void)
{
myinit();

auxReshapeFunc(reshape);
auxMainLoop(display);
}
//end of sample
///////////////////////////////////////////////////////

void glEvalMesh2(GLenum mode,GLint p1,GLint p2,GLint q1,GLint q2);

mode可以是GL_POINT GL_LINE GL_FILL。顾名思义，GL_FILL就是生成填充曲面

///////////////////////////////////////////////////////
//sample.cpp
#include "glos.h"
#include
#include
#include "windows.h"
void myinit(void);
void CALLBACK display(void);
void CALLBACK reshape(GLsizei w,GLsizei h);

GLfloat points[4][4][3]={
{{-1.5,-1.5,2.0},{-0.5,-1.5,2.0},
{0.5,-1.5,-1.0},{1.5,-1.5,2.0}},
{{-1.5,-0.5,1.0},{-0.5,1.5,2.0},
{0.5,0.5,1.0},{1.5,-0.5,-1.0}},
{{-1.5,0.5,2.0},{-0.5,0.5,1.0},
{0.5,0.5,3.0},{1.5,-1.5,1.5}},
{{-1.5,1.5,-2.0},{-0.5,1.5,-2.0},
{0.5,0.5,1.0},{1.5,1.5,-1.0}}};
GLfloat color[4][3]={
{1.0,0.0,0.0},{0.0,1.0,0.0},{0.0,0.0,1.0},{1.0,1.0,1.0}};

//初始化光照、材质的过程
void initlights(void)
{
GLfloat ambient[]={0.4,0.6,0.2,1.0};
GLfloat position[]={0.0,1.0,3.0,1.0};
GLfloat mat_diffuse[]={0.2,0.4,0.8,1.0};
GLfloat mat_specular[]={1.0,1.0,1.0,1.0};
GLfloat mat_shininess[]={80.0};
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0,GL_AMBIENT,ambient);
glLightfv(GL_LIGHT0,GL_POSITION,position);
glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);
glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);
glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess);
}

void myinit(void)
{

auxInitDisplayMode(AUX_SINGLE|AUX_RGBA);
auxInitPosition(0,0,500,500);
auxInitWindow("sample1");
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);

glMap2f(GL_MAP2_VERTEX_3,0,1,3,4,0,1,12,4,&points[0][0][0]);
glEnable(GL_MAP2_VERTEX_3);
glEnable(GL_AUTO_NORMAL);
// glEnable(GL_NORMALIZE);
glMapGrid2f(20,0.0,1.0,20,0.0,1.0);

glEnable(GL_DEPTH_TEST);
//初始化光照、材质
initlights();
}

void CALLBACK reshape(GLsizei w,GLsizei h)
{

glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);

if(w<=h)
glOrtho(-5.0,5.0,-5.0*(GLfloat)h/(GLfloat)w,
5.0*(GLfloat)h/(GLfloat)w,-5.0,5.0);
else
glOrtho(-5.0*(GLfloat)h/(GLfloat)w,
5.0*(GLfloat)h/(GLfloat)w,-5.0,5.0,-5.0,5.0);
glMatrixMode(GL_MODELVIEW);
}

void CALLBACK display(void)
{
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glColor3f(0.0,0.0,1.0);
glPushMatrix();
glRotatef(35.0,1.0,1.0,1.0);

//将原来网格的绘制部分注释掉，代替以填充曲面的绘制方法
glEvalMesh2(GL_FILL,0,20,0,20);
int i,j;
/* for(j=0;j<=8;j++)
{
glBegin(GL_LINE_STRIP);
for(i=0;i<=30;i++)
glEvalCoord2f((GLfloat)i/30.0,(GLfloat)j/8.0);
glEnd();

glBegin(GL_LINE_STRIP);
for(i=0;i<=30;i++)
glEvalCoord2f((GLfloat)j/8.0,(GLfloat)i/30.0);
glEnd();
}
*/

glPointSize(4.0);
glBegin(GL_POINTS);
for(i=0;i<4;i++)
for(j=0;j<4;j++)
{
glColor3fv(color[i]);
glVertex3fv(&points[i][j][0]);
}
glEnd();
glPopMatrix();
glFlush();

}
void main(void)
{
myinit();

auxReshapeFunc(reshape);
auxMainLoop(display);
}
//end of sample
////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////
//sample.cpp
#include "glos.h"
#include
#include
#include "windows.h"

void myinit(void);
void CALLBACK display(void);
void CALLBACK reshape(GLsizei w,GLsizei h);

//定义一组控制点的存储空间
GLfloat points[4][4][3];
//定义一个指向NURBS曲面对象的指针
GLUnurbsObj *theNurb;

//用来生成控制点的过程，取代被注释掉的原来直接赋值方式生成控制点
void init_surface(void)
{
int u,v;
for(u=0;u<4;u++)
{
for(v=0;v<4;v++)
{
points[u][v][0]=2.0*((GLfloat)u-1.5);
points[u][v][1]=2.0*((GLfloat)v-1.5);
if((u==1||u==2)&&(v==1||v==2))
points[u][v][2]=3.0;
else
points[u][v][2]=-3.0;
}
}
}
/*
GLfloat points[4][4][3]={
{{-1.5,-1.5,2.0},{-0.5,-1.5,4.0},
{0.5,-1.5,3.0},{1.5,-1.5,2.0}},
{{-1.5,-0.5,3.0},{-0.5,1.5,4.0},
{0.5,0.5,2.0},{1.5,-0.5,-1.0}},
{{-1.5,0.5,2.0},{-0.5,0.5,4.0},
{0.5,0.5,5.0},{1.5,-1.5,1.5}},
{{-1.5,1.5,-2.0},{-0.5,1.5,3.0},
{0.5,0.5,1.0},{1.5,1.5,-1.0}}};
*/
GLfloat color[4][3]={
{1.0,0.0,0.0},{0.0,1.0,0.0},{0.0,0.0,1.0},{1.0,1.0,1.0}};

void initlights(void)
{
GLfloat ambient[]={0.4,0.6,0.2,1.0};
GLfloat position[]={0.0,1.0,3.0,1.0};
GLfloat mat_diffuse[]={0.2,0.4,0.8,1.0};
GLfloat mat_specular[]={1.0,1.0,1.0,1.0};
GLfloat mat_shininess[]={80.0};
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0,GL_AMBIENT,ambient);
glLightfv(GL_LIGHT0,GL_POSITION,position);
glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);
glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);
glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess);
//首先初始化控制点
init_surface();
//创建一个NURBS曲面的对象
theNurb=gluNewNurbsRenderer();
//修改此曲面对象的属性
gluNurbsProperty(theNurb,GLU_SAMPLING_TOLERANCE,25.0);
gluNurbsProperty(theNurb,GLU_DISPLAY_MODE,GLU_FILL);
}

void myinit(void)
{

auxInitDisplayMode(AUX_SINGLE|AUX_RGBA);
auxInitPosition(0,0,500,500);
auxInitWindow("sample1");
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);

glMap2f(GL_MAP2_VERTEX_3,0,1,3,4,0,1,12,4,&points[0][0][0]);
glEnable(GL_MAP2_VERTEX_3);
glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE);
glMapGrid2f(20,0.0,1.0,20,0.0,1.0);

glEnable(GL_DEPTH_TEST);
initlights();
}

void CALLBACK reshape(GLsizei w,GLsizei h)
{

glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);

if(w<=h)
glOrtho(-5.0,5.0,-5.0*(GLfloat)h/(GLfloat)w,
5.0*(GLfloat)h/(GLfloat)w,-5.0,5.0);
else
glOrtho(-5.0*(GLfloat)h/(GLfloat)w,
5.0*(GLfloat)h/(GLfloat)w,-5.0,5.0,-5.0,5.0);
glMatrixMode(GL_MODELVIEW);
}

void CALLBACK display(void)
{
//B样条曲面（NURBS）的控制向量，可以参阅图形学的相关书籍
GLfloat knots[8]={0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0};

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glColor3f(0.0,0.0,1.0);
glPushMatrix();
glRotatef(35.0,1.0,1.0,1.0);
glRotatef(-60.0,1.0,0.0,0.0);
glScalef(0.5,0.5,0.5);

//注释掉原来的曲面绘制函数，代之以新的NURBS曲面绘制函数
// glEvalMesh2(GL_FILL,0,20,0,20);
//定义曲面的数学模型，确定其形状
gluNurbsSurface(theNurb,
8,knots,
8,knots,
4*3,
3,
&points[0][0][0],
4,4,
GL_MAP2_VERTEX_3);
//结束曲面的绘制，此结构很类似于标准的glBegin()...glEnd()
gluEndSurface(theNurb);

int i,j;
glPointSize(4.0);
glBegin(GL_POINTS);
for(i=0;i<4;i++)
for(j=0;j<4;j++)
{
glColor3fv(color[i]);
glVertex3fv(&points[i][j][0]);
}
glEnd();
glPopMatrix();
glFlush();

}
void main(void)
{
myinit();

auxReshapeFunc(reshape);
auxMainLoop(display);
}
//end of sample
//////////////////////////////////////////////////////////////////

--
※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 166.111.74.90]
• 本文已收录于以下专栏：

## OPENGL(14) c++曲面构造 网格线

• dqmengxiang
• 2010年11月17日 21:42
• 765

## VC下利用OpenGL构造自由型曲线曲面

• Ingenuus
• 2007年11月12日 15:20
• 2692

## vc+opengl绘制NURBS曲面

• feixuedudiao
• 2011年02月19日 14:40
• 1390

## 【Qt OpenGL教程】28：贝塞尔曲面

• cly116
• 2015年08月15日 18:18
• 2579

## OpenGL曲面

• Augusdi
• 2011年05月20日 15:23
• 5402

## OpenGL--贝塞尔曲线或曲面

• u010223072
• 2015年04月29日 10:32
• 4417

## OpenGL深入探索——曲面细分

• panda1234lee
• 2016年06月23日 13:23
• 1364

## 图解opengl曲线和曲面绘制

VC6 下载 http://blog.csdn.net/bcbobo21cn/article/details/44200205 opengl环境配置 http://blog.csdn.net...
• bcbobo21cn
• 2016年04月06日 11:29
• 3612

## opengl曲面贴图

opengl 曲面贴图opengl2011-02-12 15:31:16阅读5评论1  字号：大中小 订阅OpenGL曲面纹理贴图技术－－波浪的模拟    学过OpenGL的人都很容易的把图片贴到四边...
• feixuedudiao
• 2011年02月18日 11:44
• 2958