您的位置:首页 > 运维架构

MAC Cocoa Opengl入门系列教程二(OpenGl坐标系)

2016-01-22 14:54 423 查看
本章节主要教大家了解opengl中的坐标系

1.opengl中是怎样的一个坐标系?

答:opengl使用右手笛卡尔坐标系,箭头->方向为正,反为负。

         

                               


     在opengl中,-1 <= x <= 1, -1<= y <=1, -1 <= z <= 1.(默认情况下)。也就是说,若图形的坐标点不在此区域内,就看不见,这就是指摄像机剪裁区大小。

2.opengl设置视口大小和摄像机剪裁区

答:使用glViewport(GLint x, GLint y, GLsizei width, GLsizei height); 用来显示图形区域的大小。如以下代码就是设置视口大小为view视图区域大小。

- (void)prepareOpenGL
{
glClearColor(0.3, 0.3, 0.3, 1.0);
NSRect rect = self.bounds;
glViewport(0, 0, rect.size.width, rect.size.height);//通常需要设置
}


改变投影矩阵: opengl有2种投影方式,一种是正交投影(即平行投影);一种是透视投影。

正交投影:就像你看远处的物体,你看到的物体大小,就是物体本身的大小。

透视投影:就像你看远处的物体,物体离你越远,物体显得越小。

在opengl中,-1 <= x <= 1, -1<= y <=1, -1 <= z <= 1. 如果想把显示区域调大一些,即把x,y,z范围值调大。我们就得改变投影矩阵:

<span style="color:#6600cc;">//重写prepareOpenGL方法
- (void)prepareOpenGL
{
glClearColor(245.0/255, 245/255.0, 245/255.0, 1.0);
NSRect rect = [self bounds];
glViewport(0, 0, rect.size.width, rect.size.height);
glMatrixMode(GL_PROJECTION);//说明要操作的是投影矩阵
glLoadIdentity();//使用单位矩阵,
glOrtho(-1, 1, -1, 1, 1, 3);//平行投影,-1<=x<=1,-1<=y<=1
glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);使用正交投影(平行投影),前4个参数容易理解。zNear表示近距离剪裁面(必须大于0,生效),zFar为远距离剪裁面。而投影机的位置就在d(0,0,0)的位置,如果模型不在剪裁区,那么就要操作模型视图矩阵。
glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);操作透视投影剪裁区,参数与上述一致
</pre><pre name="code" class="objc"><span style="font-family: Arial, Helvetica, sans-serif;">3.opengl对模型视图进行平移、旋转、缩放,当绘制的图形或者模型不在投影区域时,我们就要对模型视图进行平移,即平移到投影区域。</span>
glMatrixMode(GL_MODELVIEW);//操作对象为模型区域矩阵
glLoadIdentity();//使用单位矩阵
glTranslatef(0, 0, -2);//沿z轴负方向平移2个单位

4.例子:opengl使用平行投影,对模型视图进行平移、旋转

#import <OpenGL/gl.h>  ///加入opengl文件头
#import <OpenGL/gl3.h> //
#import "OpenGLDrawView.h"

@implementation OpenGLDrawView

//重写prepareOpenGL方法
- (void)prepareOpenGL
{
glClearColor(245.0/255, 245/255.0, 245/255.0, 1.0);

NSRect rect = [self bounds];
glViewport(0, 0, rect.size.width, rect.size.height);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1, 1, -1, 1, 1, 3);//平行投影

// glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)//正交投影

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0, 0, -1);

//glScalef(GLfloat x, GLfloat y, GLfloat z)缩放
glRotatef(30, 0, 0, 1);//逆时针绕z轴旋转30度。
}

- (void)drawRect:(NSRect)dirtyRect {
[super drawRect:dirtyRect];

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

//定义三角形坐标点
static GLfloat vectexs[]={
-0.5,0,0,

0.5,0,0,
0,0.5,0
};

//定义颜色
static GLfloat colors[]={
1.0,0,0,
0,1.0,0,
0,0,1.0
};
//开启客户端顶点数组绘制功能
glEnableClientState(GL_VERTEX_ARRAY);
//开启客户端颜色数组绘制功能
glEnableClientState(GL_COLOR_ARRAY);
//指定顶点数组指针
glVertexPointer(3, GL_FLOAT, 0, vectexs);
//指定颜色数组指针
glColorPointer(3, GL_FLOAT, 0, colors);

//开始绘制
glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);

glFlush();
// Drawing code here.
}

@end

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息