分享
 
 
 

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

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

发信人: yxy (田丝丝#冬眠的小肥鹰), 信区: GAME_Designer

标 题: OPENGL(14)

发信站: BBS 水木清华站 (Tue Feb 17 16:24:53 1998)

曲面的构造可以是网格线和填充曲面形式,其实与曲线很类似只是变为

二维而已。

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);

以曲线坐标U V来计算曲面内任意一点的世界坐标的位置

3.曲面绘制的控制

void glMapGrid2{fd}(GLenum nu,TYPE u1,TYPE u2,GLenum nv,TYPE v1,TYPE v2);

定义曲面参数空间均匀网格,从u1到u2分为等间隔nu步,从v1到v2分为等间隔nv步。

下面给出一个以网格线描绘曲面的例子:

////////////////////////////////////////////////////////////

//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);

glLoadIdentity();

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);

glLoadIdentity();

}

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);

把用glMapGrid2{fd}()设置的网格应用到已经启用的曲面计算上。

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

这里给出一个有光照处理的BEZIER曲面的例子(这个曲面除了绘制方法不同,数学

形式和前面的是一样的)。

///////////////////////////////////////////////////////

//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();

// glShadeModel(GL_FLAT);

}

void CALLBACK reshape(GLsizei w,GLsizei h)

{

glViewport(0,0,w,h);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

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);

glLoadIdentity();

}

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

////////////////////////////////////////////////////////////////

一个真正具有实体的曲面就展现出来乐。控制点的不同,可以控制曲面的形状

可以看出OPENGL的强大功能,只用很少的原代码就产生真实的3D效果。

在以此篇结束复杂建模前,给出一个绘制NURBS曲面(非均匀B样条曲面)的例子,

这里用到乐一些OPENGL实用库提供的专门函数。所有的新东东都在程序中做乐注

释,注释给出过程的含义,具体函数的操作可以详细查阅联机手册。

///////////////////////////////////////////////////////////////

//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();

// glShadeModel(GL_FLAT);

}

void CALLBACK reshape(GLsizei w,GLsizei h)

{

glViewport(0,0,w,h);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

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);

glLoadIdentity();

}

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]

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有