也许对使用MAYA的你没什么用处,当然在编写插件代码时确实几乎不可缺少的,而且也会加深对MAYA处理机制的了解 假如我们想建立一个在U方向DIVISION为10,而在V方向DIVISION为20的网状曲面,那么偶们就可以通过下面的代码实现: [此贴子已经被作者于2007-2-6 11:14:18编辑过]
|
-
2007-04-22
-
2007-04-15
-
2007-04-10
全部评论6
-
前腐后继 2007-2-6 11:13:00
Begin again
此课开始之前还是介绍以下OPENGL中的数据类型,对于C语言绑定的OPENGL来说,它采用标准的C数据类型,只不过在前面加上“GL”例如:GLboolean,GLflaot,GLenum,GLbyte,GLshort.而这些类型前面加“u”的说明是无符号类型,e.g:
GLushort,GLubyte,GLuint.
<3>
openGL中的NURBS对象
在OPENGL中创建NURBS对象很容易,只需下面几个GLU函数就可以起用NURBS的功能:
GLUnurbsObj* gluNewNurbsRenderer(void);
//创建一个NURBS对象
void gluDeleteNurbsRenderer(GLUnurbsObj*);
//...
void gluNurbsCurve(GLUnurbsObj*,GLint knots,GLfloat *knotArray,GLint stride,GLfloat *cvArray,GLint order,GLenum type);
//定义一条NURBS曲线的形状(注意,是“形状”,含义等同于MAYA中形状的概念)。由nkont确定的结的数量;knotArray:结值数组;stride控制点之间的偏移量;cvArray用来定义控制点的值的数组(可以是3或4维的顶点,例如:GL_VERTEX_3,GL_VERTEX_4,在OPENGL内部使用的是4-类型,至于为什么,涉及数学中的"齐次坐标",而这中表示又涉及到OPENGL的效率问题,偶对此随了解些.但这不是偶们的主题,暂不鏖述);type是dD(d=1,2)求值器的类型,可用类型有:GL_MAPd_VERTEX_x(x=3,4),GL_MAPd_NORMAL,GL_MAPd_INDEX,GL_MAPd_TEXTURE_COORD_x(x=1,2,3,4).
GL_MAP1_COLOR4(使用RGBA模式)
void gluBeginCurve(GLUnurbsObj*);
//开始一个NURBS形状的定义,上面的函数必须包含在该函数和下面的结束函数之间
//
e.g:
GLfloat knot[]={
{1,0,0,1},
{0,1,0,1},
{0,0,1,1},
{0,1,1,1},
{1,0,1,1},
{1,1,0,1},
{1,1,1,1},
};
GLfloat cvArray=knot[0];
GLUnurbsObj* pobj=gluNewNurbsRenderer();
gluBeginCurve(pobj);
gluNurbsCurve(pobj,7,knot,1,cvArray,4,GL_MAP1_VERTEX_4);
gluEndCurve(pobj);
//
gluBeginCurve(
void gluEndCurve(GLUnurbsObj*);
//...
void gluNurbsSurface(GLUnurbsObj*,GLint nkontu,GLfloat * knotu,GLint strideu,...);
//参数设置和gluNurbsCurve()中的类似,只要再将除GLUnurbsObj*之外的重复一次并"u"把该成"v"即可
void glubBeginSurface(GLUnurbsObj*);
//...
void gluEndSurgace(GLUnurbsObj*);
//...
OK一次讲太多对学习也没多大益处,所以今天就讲到这里 -
前腐后继 2007-2-6 11:13:00
接下来讲一下如何在OPENGL中生成最基本的点,并由此而产生线和面
很简单,首先通过启用OPENGL中的点模式就可以使生成的点,线或面以点的形式在视图窗口中显示:
//绘制一个3维坐标为(1.0,0.5,2.0)的点,记住:OPENGL内部采用齐次坐标的形式表示点,坐标的第4个分量表示从4维空间向3维空间投射的缩放系数.从而很容易联想到用3维空间的齐次坐标表示2维空间的坐标,E.G:(2,6,4)~=(0.5,1.5)
glEnable(GL_POINTS);
glBegin(GL_POINTS);//我们还可以通过来glPointSize(GLfloat)设置点的大小,但不能放在之间。总之与下面的线和面的特征的设置函数也是如此
glVertex4f(2.0,1.0,4.0,2.0);//等价与glVertex3f(1.0,0.5,2.0)
glEnd();
同样的任何一个3维点都可以表示成为一个齐次点,而第4个分量为1,e.g:
(1,1,2)~(1,1,2,1).更广泛的形式:(x,y,z)~(x,y,z,1);
类似于点画模式,OPENGL还支持线模式和面模式;此外线模式分为:GL_LINES,GL_LINE_STRIP,GL_LINE_LOOP.而面模式支持:GL_POLYGON,GL_TRIANGLES,GL_TRIANGLE_STRIP,GL_TRIANGLE_FAN,GL_QUADS,GL_QUAD_STRIP.而这些都是基于控制点的,对于线模式,至少需要定义2个顶点,而对于面模式至少需要定义3个顶点(这是需要启用三角模式中的一种).对于各个模式类型的区别,偶们通过程序示例来解释:
在所有绘制的实际定义开始之前,都必须首先通过glEnable()启用OPENGL的相应功能,并可以通过glDisable()禁用某项功能.
glEnable(GL_LINE_STRIP);//GL_LINE_STRIP模式下,每条线段的终点都是下一条线段的起点并最终被定义为一条线,而GL_LINES模式只是从第一个顶点的定义的顺序开始,没一对顶点定义一条线段,没有端点之间的重复,若顶点数为奇数,则最后定义的顶点不被使用。而对于2个点的情况,这2种模式会产生相同的结果。但模式却隐含了一个未定义或将来有可能定义的顶点的起点(偶个人的理解)
glBegin(GL_LINE_STRIP);
glVertex3d(1,1,1);
glVertex3d(2,2,4);
glVertex3d(1,4,5);
glVertex3d(6,4,6);
glEnd();
若偶们用GL_LINE_LOOP模式代替GL_LINE_STRIP,则会生成一个闭合的线圈.它和GL_LINE_STRIP的区别仅仅是最后一个顶点自动连接到第一个顶点.这样偶有了一个有意思的想法,即:"均权性"或"周期性".也就是每个顶点都既是起点也是终点.
可以通过void glLineWidth(GLfloat)和void glLineStipple(GLint,GLushort)函数分别设置线的宽度和条纹图案。glLineStipple()的第一个参数是第二个参数的重复次数,而第二个参数是是否绘制像素的“0”,“1”序列。
对于面模式之间的区别和线模式类似:GL_POLYGON通过glBegin(),glEnd()之间定义的一系列点绘制“一个”多变形;GL_TRIANGLES每三个连续的顶点绘制三角形,但顶点不重复;GL_TRIANGLE_STRIP模式和线做同类理解;而模式GL_TRIANGLE_FAN是前3个顶点定义一个三角形,之后每个顶点都和第一个顶点和前一个顶点组合,这样会生成类似于折扇投影的三角多边扇形;其余的就是绘制4边形,这些都是多边形的基础。
That`s will leave now,so get`t over.Get flash^-^ -
前腐后继 2007-2-6 11:14:00
又要开始了。
前面讲了一些基本的功能,在继续位完成的基本功能讲解之前看来有必要将一下开发OPENGL程序的开发环境。这里特定于WINDOWS平台,因为偶用的就是WIN,当然也可以用于UNIX,LINUX,MACRO等任何具有图形卡的计算机(记住,OPENGL与平台无关)。但对于现在WINDOWS 机上常用的DIRECTX,却仅仅适用于WINDOWS;这也是偶为什么学的是OPENGL而不是它
OPENGL绑定除了C之外还有VB以及非正式的JAVA。我门这里仅对于VC++而言。首先插入带有OpenGL32.dlL和glu32.dll文件的光盘(当然如果系统已经有了就不用了)对应的库文件应该包含在...\VC\lib中("..."包容你的VC文件的路径,如:C:\program File\microsoft Visual Studio.), 包容文件应该在...VC\include\GL中。GLUT文件需要从网上获得。然后你就可以用VC++6。0开发你自己的OPENGL程序(只要你安装了VC++)。
下面介绍一下创建窗口的函数,然后你就可以利用前面学过的函数编写简单的OPENGL程序。
glutCreateWindow(GLbyte*);
GLbyte*相当与C的数据类型char*,也就是接收一个字符串,该字符串定义了窗口的标题。
//
//这个函数用来显示回调,当窗口大小或从覆盖状态恢复时,总之窗口需要重绘时都会条用该函数。
void glutDisplayFunc(userRenderFunc)
//
//导致事件的处理循环。几乎必须放在程序的最后,每个程序一次只能调用一次该函数,而且该函数调用以后不再返回只到程序结束
void glutMainLoop()
//
//这2个函数用来设置窗口的清除色,对于第2中类型的参数可以选择GL_COLOR_BUFFER_BIT,GL_DEPTH_BUFFER_BIT或者你也可以对2者使用按位或操作符:GL_COLOR_BUFFER_BIT/GL_DEPTH_BUFFER_BIT.用来清除颜色缓冲区和深度缓冲区的,也既释放该缓冲区的内存.
void glClearColor(GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha)
void glClearColor(byte)
好了精彩的节目就要开始,先写到 这里,等一会就来继续
你可能喜欢
GLUO是包含在GL工具库里的函数,算不上真正的OPENGL函数。但是却可以在OPENGL编程中直接使用,当然必须在VC++或其他平台上安装了相应的头文件。
下面是几个用于创建简单的2次曲面的GLU函数:
GLUquadricObj* gluNewQuadric();
//创建一个新的2次曲面对象,并返回一个指向该对象的指针
void gluDeleteQuadric(GLUquadricObj*);
//删除又2次对象指针指定的2次曲面
void gluSphere(GLUquadricObj* pobj,GLdouble radius,GLint silces,GLint stacks);
//创建球体
void gluCylinder(GLUquadricObj* pobj,GLdouble baseRadius,GLdouble topRadius,GLint slices,GLint stacks);
//创建圆柱体
void gluDisk(GLUquadricObj* pobj,GLdouble innerRadius,GLdouble outerRadius,GLint slices,GLint stacks);
//创建圆环盘,innerRadius,outerRadius分别指定了内径和外径
让偶们来举个创建2次对象的简单e.g:
//创建一个半径为5,在经线和纬线方向细分数为10的球体
GLUquadricObj *pobj;
pobj=gluNewQuadric();
gluQuadricDrawStyle(pobj,GLU_LINE);//确定几何体的绘制模式(GLU_LINE)
gluSphere(pobj,5,10,10);
下面几个是创建GLUT对象的函数,是对GLU的补充
void glutWireSphere(GLdouble radius,GLint slices,GLint stacks);
//创建线框球体
void glutSolidSphere(GLdouble radius,GLint slices,GLint stacks);
//创建实心球体
void glutWireCone(GLdouble baseRadius,GLdouble height,GLint slices,GLint stacks);
void glutSolidCone(GLdouble baseRadius,GLdouble height,GLint slices,GLint stacks);
void glutWireTorus(GLdouble innerRadius,GLdouble outerRadius,GLint slices,GLint stacks);
void glutSolidTorus(GLdouble innerRadius,GLdouble outerRadius,GLint slices,GLint stacks);
//
//下面的几个函数是用来创建柏拉图(即正多面体),所有的顶点都定义在一个单位员上,由于这些都是确定类型的多面体,因此顶点数已经定义于内部,因此不需要指定参数
void glutWireTetrahedron();
void glutSolidTetrahedron();
void glutWireOctahedron();
void glutSolidOctahedron();
void glutWireDodecahedron();
void glutSolidDodecahedron();
void glutWireIcosahedron();
void glutSolidIcosahedron();
OK,today over at now. See again tomorrow!