OpenGL学习08_几何变换

OpenGL需要通过视图变换,模型变换,投影变换,视口变换,绘制场景这一系列步骤将图像绘制出来。

1、模型变换和视图变换

从“相对移动”的观点来看,改变观察点的位置与方向和改变物体本身的位置与方向具有等效性。在OpenGL中,实现这两种功能甚至使用的是同样的函数。由于模型和视图的变换都通过矩阵运算来实现,在进行变换前,应先设置当前操作的矩阵为“模型视图矩阵”。设置的方法是以GL_MODELVIEW为参数调用glMatrixMode函数。

glMatrixMode(GL_MODELVIEW);
通常,我们需要在进行变换前把当前矩阵设置为单位矩阵,

glLoadIdentity();

进行模型和视图变换,主要涉及到三个函数:
glTranslate*,把当前矩阵和一个表示移动物体的矩阵相乘。三个参数分别表示了在三个坐标上的位移值。
glRotate*,把当前矩阵和一个表示旋转物体的矩阵相乘。物体将绕着(0,0,0)到(x,y,z)的直线以逆时针旋转,参数angle表示旋转的角度。
glScale*,把当前矩阵和一个表示缩放物体的矩阵相乘。x,y,z分别表示在该方向上的缩放比例。

2、投影变换

投影变换就是定义一个可视空间,可视空间以外的物体不会被绘制到屏幕上。OpenGL支持两种类型的投影变换,即透视投影和正投影。投影也是使用矩阵来实现的。如果需要操作投影矩阵,需要以GL_PROJECTION为参数调用glMatrixMode函数。

glMatrixMode(GL_PROJECTION);

通常,我们需要在进行变换前把当前矩阵设置为单位矩阵。使用glFrustum函数可以将当前的可视空间设置为透视投影空间,也可以使用更常用的gluPerspective函数。正投影相当于在无限远处观察得到的结果,它只是一种理想状态。但对于计算机来说,使用正投影有可能获得更好的运行速度。使用glOrtho函数可以将当前的可视空间设置为正投影空间。

3、视口变换
当一切工作已经就绪,只需要把像素绘制到屏幕上了。这时候还剩最后一个问题:应该把像素绘制到窗口的哪个区域呢?通常情况下,默认是完整的填充整个窗口,但我们完全可以只填充一半。(即:把整个图象填充到一半的窗口内),使用glViewport来定义视口。其中前两个参数定义了视口的左下脚(0,0表示最左下方),后两个参数分别是宽度和高度。

下面通过一个例子来看一下OpenGL的变换如何使用。

//
//  main.cpp
//  OpenGL_09_Model
//
//  Created by apple on 15/1/13.
//  Copyright (c) 2015年 cc. All rights reserved.
//

#include <iostream>

#include <GLUT/GLUT.h>

/**
 *  初始化操作
 */
void init() {
    //设置清屏色
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    //设置着色模式,填充色与顶点一致
    glShadeModel(GL_FLAT);
}

/**
 *  绘制三角形
 */
void draw_triangle() {
    glBegin(GL_LINE_LOOP);
    glVertex2f(0.0, 25.0);
    glVertex2f(25.0, -25.0);
    glVertex2f(-25.0, -25.0);
    glEnd();
}

/**
 *  展示绘制效果
 */
void display() {
    
    //清理颜色缓冲区
    glClear(GL_COLOR_BUFFER_BIT);
    //设置绘制颜色
    glColor3f(1.0, 1.0, 1.0);
    
    
    //1.使用实线绘制三角形
    
    //加载单位矩阵,隔离各个模型的变换效果
    glLoadIdentity();
    //设置绘制颜色
    glColor3f(1.0, 1.0, 1.0);
    //绘制三角形
    draw_triangle();

    //2.使用点画虚线绘制三角形,进行平移模型变换

    //开启点画线功能
    glEnable(GL_LINE_STIPPLE);
    //设置点画模式,使用短虚线
    glLineStipple(1, 0xF0F0);
    //加载单位矩阵
    glLoadIdentity();
    //沿x轴负方向平移20像素
    glTranslatef(-20.0, 0.0, 0.0);
    //绘制三角形
    draw_triangle();
    
    //3.使用点画虚线绘制三角形,进行缩放模型变换

    //设置点画模式,使用长虚线
    glLineStipple(1, 0xF00F);
    //加载单位矩阵
    glLoadIdentity();
    //设置缩放,X轴方向放大1.5倍,Y轴方向所辖0.5倍
    glScalef(1.5, 0.5, 1.0);
    //绘制三角形
    draw_triangle();
    
    //4.使用点画虚线绘制三角形,进行缩放模型变换

    //设置点画模式,使用长虚线
    glLineStipple(1, 0x8888);
    //加载单位矩阵
    glLoadIdentity();
    //设置旋转,沿Z轴顺时针旋转90度
    glRotatef(90.0, 0.0, 0.0, 1.0);
    //绘制三角形
    draw_triangle();
    
    //关闭点画线功能
    glDisable(GL_LINE_STIPPLE);
    
    //强制完成绘制指令
    glFlush ();
}

/**
 *  调整窗口尺寸
 *
 *  @param width  宽度
 *  @param height 高度
 */
void reshape(int width, int height) {
    //设置视口矩形区域,在默认情况下,视口被设置为占据打开窗口的整个像素矩形
    glViewport(0, 0, (GLsizei)width, (GLsizei)height);
    //之后的矩阵操作定义为投影矩阵操作
    glMatrixMode(GL_PROJECTION);
    //等于是将之前矩阵变换导致变化过的栈顶矩阵重新归位,置为单位矩阵!等于是之前的矩阵变换带来的影响到此为止了!
    glLoadIdentity();
    
    //它创建一个平行视景体,实际上这个函数的操作是创建一个正射投影矩阵,并且用这个矩阵乘以当前矩阵
    if (width <= height)
        glOrtho(-50.0, 50.0, -50.0 * (GLfloat)height / (GLfloat)width,
                 50.0 * (GLfloat)height / (GLfloat)width, -1.0, 1.0);
    else
        glOrtho(-50.0 * (GLfloat)width / (GLfloat)height,
                 50.0 * (GLfloat)width / (GLfloat)height, -50.0, 50.0, -1.0, 1.0);
    //之后的矩阵操作定义为模型视图矩阵操作
    glMatrixMode(GL_MODELVIEW);

}

int main(int argc, const char * argv[]) {
    
    //初始化GLUT库
    glutInit(&argc, (char**)argv);
    //设置单缓冲,RGB像素格式的窗口
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    //设置窗口大小
    glutInitWindowSize(500, 500);
    //设置窗口坐标
    glutInitWindowPosition (100, 100);
    //创建窗口
    glutCreateWindow("Model");
    
    //初始化操作
    init();
    
    //设置展示的回调方法
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    
    //绘制线程开始循环
    glutMainLoop();
    
    return 0;
}

本文由CC原创总结,如需转载请注明出处:http://blog.csdn.net/oktears/article/details/42915159

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值