有网站模板怎么做网站,ps做网站难吗,济南网站建设正规公司,网站建设工作落实情况1、本节实现的内容
上一节我们创建一个简单的窗口#xff0c;本节我们需要了解一下细节内容#xff0c;同时为了方便观看#xff0c;我们需要显示一个世界坐标轴#xff0c;建立一个直观的三维空间。
2、我们的眼睛设定#xff08;gluPerspective函数#xff09;
上一…1、本节实现的内容
上一节我们创建一个简单的窗口本节我们需要了解一下细节内容同时为了方便观看我们需要显示一个世界坐标轴建立一个直观的三维空间。
2、我们的眼睛设定gluPerspective函数
上一节课我们创建了一个简单的opengl窗口并显示了一个简单的3d模型正方体这节我们就要开始了解更多的细节内容。嗯上一节课中使用了视角的设置函数perspective第一个参数表示视场角的大小符合人眼的条件一般设置为40°~70°之间这个函数。在我理解有点像是你眼睛展开的角度比如说10度就有点像你能观测的范围只有10度就像眯着眼睛看世界那么他看到的物体就范围比较窄如果你设置的是60度那么它光视角就会更大一些看到的范围更多。这一点可以在我们后期从三维坐标转换到屏幕的二维坐标中体会到说当前的这个角度是60度在坐标转换中一个三维坐标点A如果在当前视角的屏幕以外那么它A点与当前屏幕正中间点的视线夹角肯定就超过了60度我们在后期讲解三维坐标转换时会讲到。
void gluPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear,GLdouble zFar)fovy视角的大小相当于眼睛张开的角度。当视角为0度时这就相当于我们的眼睛闭起来了那就神马也看不到了。所以选择一个合适的视角尤为重要一般40度至70度最适合当然具体情况具体分析。
aspect宽和高的比例这里我们直接可以取程序窗口的宽度和高度比。
zNear观察点与近侧裁剪平面的距离眼睛距离近处的距离一般选择0.01。
zFar观察点与远侧裁剪平面的距离眼睛远处的裁面一般为1000超过这个距离将被裁剪看不到。
zNear和zFar说明了对于绘制的图形它与视线原点的距离0.01到1000之间必须是在两者之间。 3、我们看向远方的视线gluLookAt函数
我们还用到了一个函数gluLookAt这个函数形象的表述了我们在三维世界里头眼睛所在的位置和朝向的位置还有一个视角的方向。
void gluLookAt(GLdouble eyex,GLdouble eyey,GLdouble eyez,GLdouble centerx,GLdouble centery,GLdouble centerz, GLdouble upx,GLdouble upy,GLdouble upz);前两个非常的好理解第一个参数就表示的是你眼睛的位置第二个参数就表示你要看物体的位置坐标当然我们第二个参数可以不确定到具体的物体位置坐标只要你向前看视线上的任何一点都可以。第三个参数要是你视线的正上方向量根据设定角度不同可以实现侧着头观察世界的效果。
4、通过我们的眼睛和视线探索世界
通过我们前面讲到的我们的眼睛设定gluPerspective函数和我们看向远方的视线gluLookAt函数我们就可以描述出我们观察时间的方式。还拿上节课的例子我们通过gluPerspective将眼睛以45度的角度睁开我的眼睛位于一个10.0f,10.0f,10.0f点的位置视线朝着原点0.0f,0.0f,0.0f点的位置望去这就是我们以下代码大致实现的内容。 //获取窗口大小RECT tempClientRect;GetClientRect(hWnd,tempClientRect);//初始化3D视角glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(45,(float)tempClientRect.right/(float)tempClientRect.bottom,0.01f,1000.0f);glMatrixMode(GL_MODELVIEW);glLoadIdentity();//设置用户眼睛视角展示壮观的三维世界从这里开始gluLookAt(10.0f,10.0f,10.0f,0.0f,0.0f,0.0f,0.0f,1.0f,0.0f);说到这里后期当我们不停地改变眼睛的位置和视线的方向就产生了视角移动的效果可以产生人物移动观察世界的效果类似第一人称射击游戏或RPG游戏人物视角的效果是不是很有感觉我们将在后期完善相关代码随后再详细说。
5、窗口显示比例的锁定
当我们创建了视角以后我们发现一个问题当我们鼠标拖动窗口改变大小时我们刚刚显示的物体竟然变形状了而且立方体的位置不再显示在窗口的中心。试想以下我们如果在玩游戏出现人物如果会随着程序窗口大小的改变而不断地被拉长或压扁那将是个多么糟糕的事情。因此我们需要另一个函数来保证所有的物体保持横宽比例。 OpenGL中的glViewport 函数用于定义视口Viewport也就是确定窗口中显示的区域。它的定义如下
void glViewport(GLint x, GLint y, GLsizei width, GLsizei height);x视口的左下角X坐标。
y视口的左下角Y坐标。
width视口的宽度。
height视口的高度。
glViewport函数的作用是将正投影坐标OpenGL的默认坐标系映射到屏幕上实际显示的区域。它将正投影坐标系中的点映射到屏幕上指定大小的矩形区域内。这里我们将的glViewport(0,0,tempClientRect.right,tempClientRect.bottom)就时将整个程序窗口平面设定为显示区域那么配合着gluPerspective中设定的平面横纵比为(float)tempClientRect.right/(float)tempClientRect.bottom我们就可以保持整个世界的横纵比例保持一致不至于出现拉长、压扁的情况了。 //获取窗口大小RECT tempClientRect;GetClientRect(hWnd,tempClientRect);//重置视窗设置glViewport(0,0,tempClientRect.right,tempClientRect.bottom);glMatrixMode(GL_PROJECTION);glLoadIdentity();在使用OpenGL进行绘图时我们通常需要先通过glViewport来设置视口将整个窗口或窗口的一部分作为渲染区域。这样我们可以指定绘制的内容在窗口的哪个位置显示出来。通常情况下我们将glViewport放置到窗口改变的消息处理函数中即可但如果后期需要显示多个glViewport视口就需要改变glViewport的设置位置。
大家还记不记得魔兽争霸3游戏界面里的人物选中头像界面在二维平面相框中显示出来三维的头像就可以个用glViewport实现出来我们将在后面的程序中实现这一个功能敬请期待。 6、我们需要一个三维坐标轴
接下来我们看到的立方体是在一个黑色窗口里面仿佛悬浮在空中一样没有参照物我们要创建一个可以看见的三维坐标轴方便观察。大家需要明确的一点是openGL中世界坐标系World Coordinates是右手坐标系在二维屏幕上屏幕水平方向是x 轴方向向右为正屏幕竖起方向是Y轴方向向上为正垂直于屏幕的方向是Z轴方向从屏幕里往外为正。 我们首先去生成一个坐标轴我们需要使用的画线操作。OpenGL的绘图的函数很多OpenGL的绘图必须在在glBegin()和glEnd()函数之间完成这里简单介绍基本几何绘图函数。
GL_POINTS单个顶点集 GL_LINES 多组双顶点线段 GL_POLYGON 单个简单填充凸多边形 GL_TRAINGLES多组独立填充三角形 GL_QUADS多组独立填充四边形 GL_LINE_STRIP 不闭合折线 GL_LINE_LOOP 闭合折线 GL_TRAINGLE_STRIP 线型连续填充三角形串 GL_TRAINGLE_FAN 扇形连续填充三角形串 GL_QUAD_STRIP 连续填充四边形串
具体的使用方法上图一目了然。这个图我已经收藏了用的时候超方便。 有了这些方法我们就可以采用其中的GL_LINES 多组双顶点线段来画我们的三维坐标轴了。这里我们用红色的线表示x轴绿色的线表示y轴蓝色线表示z轴。箭头方向的表示对应轴线的正值方向另外一边就是负值方向。 //显示坐标轴if(true){//设置线的宽度glLineWidth(3.0f);//显示红色的X坐标轴glColor3f(1.0f,0.0f,0.0f);glBegin(GL_LINES);glVertex3f(-10.0f,0.0f,0.0f);glVertex3f(10.0f,0.0f,0.0f);glEnd();//显示绿色的Y坐标轴glColor3f(0.0f,1.0f,0.0f);glBegin(GL_LINES);glVertex3f(0.0f,-10.0f,0.0f);glVertex3f(0.0f,10.0f,0.0f);glEnd();//显示蓝色的Z坐标轴glColor3f(0.0f,0.0f,1.0f); glBegin(GL_LINES);glVertex3f(0.0f,0.0f,-10.0f);glVertex3f(0.0f,0.0f,10.0f);glEnd();}添加以上代码后我们就可以看到一个简陋的坐标轴了。 7、添加坐标轴的方向箭头
我们画出了坐标轴但是没有方向箭头总感觉少点什么。我么还是把方向箭头显示出来这样我们就可以明确的感知到各个方向的正方向和负方向的区别了。
这里我们箭头使用了前面正方体类似的系统函数系统还提供了类似四面体、正八面体、正十二面体、正二十面体、球体、圆环体、茶壶等多个基础函数方便用户使用。 //显示一个椎体glutSolidCone(0.5,1.0,30,30);当然系统提供的这些函数画出的立体图形只有默认的方向如果用户想调整立体图形的方向和位置就要用到转换矩阵相关函数。我们这里简单介绍一下
void glTranslatef(GLfloat x,GLfloat y,GLfloat z);函数功能简单的理解就是物体的位置移动。参数xyz分别指定沿xyz轴方向的平移分量。其作用就是将你绘点坐标的原点在当前原点的基础上平移一个(x,y,z)向量。
void glRotatef(GLfloat angle,GLfloat x,GLfloat y,GLfloat z);函数功能简单的理解就物体的旋转。先解释一下旋转方向做(0,0,0)到(x,y,z)的向量方向满足右手定则用右手握住这条向量大拇指指向向量的正方向四指环绕的方向就是旋转的方向。以点(0,0,0)到点(x,y,z)为轴旋转angle角度。
接下来我们就可以使用glTranslatef和glRotatef函数对圆锥箭头进行位置和角度的调整。在Opengl中存在大量的位置和角度的调整后期还会详细了解以上操作函数。 //显示坐标轴箭头glPushMatrix();glColor3f(1,0,0);glTranslatef(10,0,0);glRotatef(90,0.0f,1.0f,0.0f);glutSolidCone(0.5,1.0,30,30);glPopMatrix();//显示坐标轴箭头glPushMatrix();glColor3f(0,1,0);glTranslatef(0,10,0);glRotatef(-90,1.0f,0.0f,0.0f);glutSolidCone(0.5,1.0,30,30);glPopMatrix();//显示坐标轴箭头glPushMatrix();glColor3f(0,0,1);glTranslatef(0,0,10);glRotatef(0,1.0f,0.0f,0.0f);glutSolidCone(0.5,1.0,30,30);glPopMatrix();