opengl怎么植物建模(opengl绘制)
基本几何图元是OpenGL进行建模的最基本的方法,但其对较复杂真实物体的建模则比较困难。对于这些复杂物体的建模,需要用到OpenGL基本库和功能库函数(gl库和glu库)以对图元进行扩展并完成法向计算、曲线生成和曲面构造等内容。这种对基本图元的扩展实际也就是对点、线及多边形的扩展。OpenGL中定义的点可具有不同大小的尺寸,其扩展的函数形式为:
void glPointSize(GLfloat size);
其参数size以象素为单位设置了点的宽度,其值必须为正,缺省值1.0。对于线的扩展,可通过下面的函数来分别指定其宽度和绘制类型:
void glLineWidth(GLfloat width);
void glLineStipple(GLint factor,GLushort pattern);
glLineWidth()的参数width以象素为单位指定线宽,其值必须为正,缺省值为1.0。glLineStipple()的参数factor为对模式进行拉伸的比例因子,参数pattern指定了线的模式(例如11001100将绘制一条虚线,为1时绘制,为0时不绘制)。该函数只有在启用了函数glEnable(GL_LINE_STIPPLE)后才可以使用,当不再使用时调用glDisable(GL_LINE_STIPPLE)将其关闭。扩展多边形的绘制模式包括全填充式、轮廓点式、轮廓线式及图案填充式等几种。使用时,首先调用glPolygonMode()设置多边形的模式设置:
void glPolygonMode(GLenum face,GLenum mode);
参数face为GL_FRONT、GL_BACK或GL_FRONT_AND BACK;mode取值可以是GL_POINT、GL_LINE或GL_FILL,分别表示多边型的轮廓点、轮廓线和填充模式的绘制方式。缺省设置为填充模式。设置完成后可进行图案填充的设置:
void glPolygonStipple(const GLubyte *mask);
其参数mask必须为一指向32×32大小的位图的指针,值为1时绘制、为0不绘制。该函数的使用同样也需要进行如下启动、关闭设置:
glEnable(GL_POLYGON-STIPPLE);
glDisable(GL_POLYGON_STIPPLE);
复杂模型的建模不同与简单模型的建模,在简单模型中一个平面上各点的法向(mormal vector)是一样的,均等于此平面的法向。对于复杂模型中由众多小的平面多边形逼近而成的曲面,其每个顶点的法向量都不一样,因此曲面上每个点的法向计算结果根据采取的不同算法而有不同的结果。OpenGL只提供赋予当前顶点法向量的函数,而不提供对法向量计算的方法,法向量的计算需要由开发者来完成。下面给出一种简单的计算方法:
void getNormal(GLfloat gx[3],GLfloat gy[3],GLfloat gz[3],GLfloat *ddnv)
{
GLfloat w0,w1,w2,v0,v1,v2,nr,nx,ny,nz;
w0=gx[0]-gx[1];
w1=gy[0]-gy[1];
w2=gz[0]-gz[1];
v0=gx[2]-gx[1];
v1=gy[2]-gy[1];
v2=gz[2]-gz[1];
nx=(w1*v2-w2*v1);
ny=(w2*v0-w0*v2);
nz=(w0*v1-w1*v0);
nr=sqrt(nx*nx+ny*ny+nz*nz);
ddnv[0]=nx/nr;
ddnv[1]=ny/nr;
ddnv[2]=nz/nr;
}
其参数gx[3],gy[3]和gz[3]为逼近曲面的一个三角形的三个顶点P0,P1和P2。通过计算矢量P0-P1与矢量P2-P1的叉乘而得到其平面法向量,并在归一化后保存到由参数ddnv所指向的数组中。至于顶点法向的计算则多是取邻近平面法向量的均值。OpenGL提供的法向定义函数为:
void glNormal3{bsifd}(TYPE nx,TYPE ny,TYPE nz);
void glNormal3{bsifd}v(const TYPE *v);
OpenGL入门 - 1
简单来说就是实现图形的底层渲染
A. 比如在游戏开发中,对于游戏场景/游戏人物的渲染
B. 比如在音视频开发中,对于视频解码后的数据渲染
C. 比如在地图引擎,对于地图上的数据渲染
D. 比如在动画中,实现动画的绘制
E. 比如在视频处理中,对于视频加上滤镜效果
OpenGL/OpenGL ES/Metal 在任何项目中解决问题的本质就是利用 GPU 芯片来高效渲染图形图像。
图形 API 是 ios 开发者唯一接近 GPU 的方式。
OpenGL 阶段:
OpenGL ES 阶段:
Metal 阶段:
固定管线/存储着⾊器
顶点数据是由CPU/GPU来处理?
顶点缓存区:区域(不在内存!-显卡显存中。)
片元着色器
像素着色器
片元函数
GPUImage
[-1,1]标准化设备坐标系(NDC)
物体/世界/照相机空间-右手系
规范化设备坐标:左手系。
x,y,z = 0,1,2
注意OpenGL中坐标系 OpenGL中的物体,世界,照相机坐标系都属于右手坐标系,而规范化设备坐标系(NDC)属于左手坐标系。笼统的说OpenGL使用右手坐标系是不合适的
OpenGL希望每次顶点着色后,我们的可见顶点都为标准化设备坐标系 (Normalized Device Coordinate, NDC)。也就是说每个顶点的x,y,z都应该在-1到1之间,超出这个范围的顶点将是不可见的。
通常情况下我们会自己设定一个坐标系范围,之后再在顶点着色器中将这些坐标系变换为标准化设备坐标,然后这些标准化设备坐标传入光栅器(Rasterizer),将他们变换为屏幕上的二维坐标和像素。
将坐标变换为标准化设备坐标,接着再转化为屏幕坐标的过程通常是分布进行的,也是类似于流水线那样。在流水线中,物体的顶点在最终转化为屏幕坐标之前还会被变换到多个坐标系系统(Coordinate System)。将物体的坐标变到几个过渡坐标系(Intermediate Coordinate System)的优点在于 在这些特定的坐标系统中,一些操作或运算更加方便和容易,这一点很快就变得明显。对我们来说比较重要的总共有5个不同的坐标系统。
这是一个顶点在最终被转化为片段之前需要经历的所有不同的状态。为了将坐标从一个坐标系变换到另一个坐标系,我们需要用到几个变换矩阵,最重要的几个分别是 模型(Model)、观察(View)、投影(Projection)三个矩阵。
物体顶点的起始坐标在局部空间(Local Space),这里称为局部坐标(Local Coordinate),他在之后在变成世界坐标(World Coordinate),观察坐标(View Coordinate),裁剪坐标(Clip Coordinate),并最后转为屏幕坐标(Screen Coordinate)
的形式结束。
物体坐标系: 每个物体都有他独立的坐标系,当物理移动或者改变方向时。该物体相关联的坐标系将随之移动或改变方向。
物体坐标系是以物体本身而言,比如,我先向你发指令,”向前走一步“,是向你的物体坐标系发指令。我并不知道你会往哪个绝对的方向移动。比如说,当你开车的时候,有人会说向左转,有人会说向东。但是,向左转是物体坐标系的概念,而向东则是世界坐标系概念。
在某种情况下,我们可以理解物体坐标系为模型坐标系。因为模型顶点的坐标都是在模型坐标系中描述的。
照相机坐标系: 照相机坐标系是和观察者密切相关的坐标系。照相机坐标系和屏幕坐标系相似,差别在于照相机坐标系处于3D空间中,而屏幕坐标系在2D平面里。
为什么要引入惯性坐标系? 因为物体坐标系转换到惯性坐标系只需要旋转,从惯性坐标系转换到世界坐标系只需要平移。
OpenGL最终的渲染设备是2D的,我们需要将3D表示的场景转换为最终的2D形式,前面使用模型变换和视觉变换将物体坐标转到照相机坐标系后,需要进行投影变换,将坐标从照相机坐标系转换为裁剪坐标系,经过透视除法后,变换到规范化设备坐标系(NDC),最后进行视口变换后,3D坐标才变换到屏幕上的2D坐标,这个过程入下图:
在上面的图中, 注意,OpenGL只定义了裁剪坐标系、规范化设备坐标系、屏幕坐标系,而局部坐标系、世界坐标系、照相机坐标系都是为了方便用户设计而自定义的坐标系,他们的关系如下图:
OpenGL 然后对裁剪坐标执行透视除法从而将他们变换到标准化设备坐标。 OpenGL 会使用glViewPort内部的参数来将标准化设备坐标映射到屏幕坐标,每个坐标关联一个屏幕上的点。这个过程称为视口变换
局部坐标系(模型坐标系)是为了方便构造模型而设立的坐标系,建立模型时我们无需关心最终对象显示在屏幕那个位置。
模型变换的主要目的是通过变换使得用顶点属性定义或者3d建模软件构造的模型,能够按照需要,通过缩小、平移等操作放置到场景中合适的位置, 通过模型变换后,物体放置在一个全局的世界坐标系中,世界坐标系是所有物体交互的一个公共坐标系
视变换是为了方便观察场景中物体而建立的坐标系,在这个坐标系中相机是个假设的概念,是为了便于计算而引入的。相机坐标系中的坐标,就是从相机的角度来解释世界坐标系中的位置
OpenGL中相机始终位于原点,指向 -Z轴,而以相反的方式来调整场景中物体,从而达到相同的观察效果。例如要观察-Z轴方向的一个立方体的右侧面,可以有两种方式:
GLShaderManager的初始化
GLShaderManager shaderManager;
shaderManager.InitializeStockShaders();
求助:有人用opengl做过植物生长可视化方面OpenGL函数库相关的API有核心库(gl)、实用库(glu)、辅助库(aux)、实用工具库(glut)、窗口库(glx、agl、wgl)和扩展函数库等。从图1可以看出,gl是核心,glu是对gl的部分封装。glx、agl、wgl是针对不同窗口系统的函数。glut是为跨平台的OpenGL程