OpenGL学习笔记(一):环境搭建、三维空间坐标系理解以及OpenGL的基本使用

来源:互联网 发布:乌鲁木齐乐知少儿英语 编辑:程序博客网 时间:2024/06/05 11:03

原博主博客地址:http://blog.csdn.net/qq21497936
本文章博客地址:http://blog.csdn.net/qq21497936/article/details/78660326


OpenGL学习笔记(一):环境搭建、三维空间坐标系理解以及OpenGL的基本使用

前话

        经常看到技术需求当中有opengl,所以有时间就介绍并学习下opengl,opengl对于qt来说只是窗口不一样,其调用的实际函数都是opengl的原生函数,所以这可以说学会opengl是完全意义上的一通百通。

Qt for OpenGL

        Qt5.2 OpenGL 下载地址:
             http://download.qt.io/archive/qt/5.2/5.2.0/qt-windows-opensource-5.2.0-mingw48_opengl-x86-offline.exe    

      《OpenGL编程指南(原书第8版)中文高清版.pdf》下载地址:
             http://download.csdn.net/download/qq21497936/10137423
   

Demo

        
        源码下载地址:http://download.csdn.net/download/qq21497936/10136743

OpenGL坐标系理解


        在OpenGL里面移动坐标是相对于当前点开始移动的相对坐标;

        在OpenGL里面绕轴变换,每次画图形之前会设置一个变换原点,变换的轴必须通过该点,所以要实现理想的变换,必须很好的掌握此相对于变换图形的“原点”(非整体坐标系原点)。

OpenGL基本窗口建立

        安装完成后,新建一个Qt QGui程序,使用QWdiget做为基类,声明自己的窗口类(OpenGL显示窗口),如下图:


        创建完成后,首先就是要该窗口继承的基类QWidget改为QGLWidget。

        在工程文件.pro加入:

QT += opengl
        头文件加入,特别注意包含GL/glu,否则调用glu函数会没有
#include <QGLWidget>#include <GL/glu.h>    // 必须包含,否则glu相关函数无法使用
        重载三个函数
protected:    void initializeGL();                  // 用来初始化    void paintGL();                       // 用来绘制,更新发生,就会被调用    void resizeGL(int width, int height); // 窗口大小变化时,会调用

        至此Qt OpenGL基本的程序窗口搭建完毕,不论任何语言的opengl的使用,除了之前创建窗口不同之外,以下opengl学习调用的函数为opengl的原生函数。

OpenGL基本使用

初始化窗口代码

void NeHeWidget::initializeGL() // 每次paintgGL()或resizeGL()之前会自动调用{    // 启用smooth shading(阴影平滑)    glShadeModel(GL_SMOOTH);    // 设置清楚屏幕所用的颜色 色彩值范1围从0.0-1.0 (R G B A) 清屏时A不起作用    glClearColor(0.1, 0.1, 0.4, 1.0);    /* 以下三行必须做,是关于深度缓存的,深度缓存是OpenGL十分重要的部分*/    // 设置深度缓存    glClearDepth(1.0);    // 启用深度测试    glEnable(GL_DEPTH_TEST);    // 设置深度测试的类型    glDepthFunc(GL_LEQUAL);    // 设置希望得到最好的透视修正    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);}

画一个三角形和一个四边形,填充颜色,并让三角形饶Y轴变换,四边形绕X轴变换

void NeHeWidget::paintGL(){    // 清除屏幕和深度缓存    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    // 重置观察矩阵/投影矩阵    // (X坐标轴从左至右,Y坐标轴从下至上,Z坐标轴从里至外)    // OpenGL屏幕中心的坐标值是X和Y轴上的0.0点    // 中心左面的坐标值是负值,右面是正值。    // 移向屏幕顶端是正值,移向屏幕底端是负值。    // 移入屏幕深处是负值,移出屏幕则是正值。    glLoadIdentity();    // 沿着X、Y、Z轴移动    // X轴左移1.5个单位,Y轴不动(0.0),最后移入屏幕6.0个单位    // 注意在glTranslatef(x, y, z)中当您移动的时候,    // 您并不是相对屏幕中心移动,而是相对与当前所在的屏幕位置    glTranslatef(-1.5, 0.0, -6.0);    // 让对象绕某个轴旋转 绕 Y 轴旋转三角形    glRotatef(rTri, 0.0, 1.0, 0.0); 注意:X轴旋转,X,Y,Z可调整绕哪个轴    // glBegin(GL_TRIANGLES)开始绘制三角    // 以目前所在的点为画图原点(0,0,0) 开始相对原点坐标画三角形    glBegin(GL_TRIANGLES);    glColor3f( 1.0, 0.0, 0.0 );    // 红色        颜色+顶点    glVertex3f( 0.0,  1.0,  0.0);  // 中上顶点    红色+中上    glColor3f( 0.0, 1.0, 0.0 );    // 绿色    glVertex3f(-1.0, -1.0,  0.0 ); // 左下顶点    绿色+左下    glColor3f( 0.0, 0.0, 1.0 );    // 蓝色    glVertex3f( 1.0, -1.0,  0.0 ); // 右下顶点    蓝色+右下    // glEnd()告诉OpenGL图形(三角)已经创建好了    // 三点间自动使用渐变填充    glEnd();    // 重置模型观察矩阵 重置模型观察矩阵之后,X、Y、Z轴都以复位    glLoadIdentity();    glTranslatef( 1.5,  0.0,  -6.0 );            // 移动到点    // 绕 X 轴旋转四边形 注意:X轴旋转,X,Y,Z可调整绕哪个轴    glRotatef(rQuad, 1.0, 0.0, 0.0);    // 绘制四边形    // 以目前所在的点为画图原点(0,0,0) 开始相对原点坐标画四边形    glBegin( GL_QUADS );    glColor3f( 0.5, 0.5, 1.0 ); // 蓝色,下面画的点都是蓝色直到换颜色后换点    glVertex3f(-1.0,  1.0,  0.0 ); // 左上顶点    glVertex3f( 1.0,  1.0,  0.0 ); // 右上定点    glVertex3f( 1.0, -1.0,  0.0 ); // 右下定点    glVertex3f(-1.0, -1.0,  0.0 ); // 坐下定点    glEnd();}

每当窗口做大小改变的时候,我们需要resizeGL整个窗口大小

void NeHeWidget::resizeGL(int width, int height){    // 防止height为0    if(height == 0)    {        height = 1;    }    // 重置当前的视口    glViewport(0, 0, (GLint)width, (GLint)height);    // 选择投影矩阵    glMatrixMode(GL_PROJECTION);    // 重置观察矩阵/投影矩阵 当调用次函数,实际将当前点移到了屏幕中心    glLoadIdentity();    // 建立透视投影矩阵,需要<GL/glu.h>头文件    gluPerspective( 45.0, (GLfloat)width/(GLfloat)height, 0.1, 100.0 );    // 选择模型观察矩阵    glMatrixMode( GL_MODELVIEW );    // 重置观察矩阵/投影矩阵    glLoadIdentity();}

最后我们需要不断的定时修改旋转角度,修改后需要刷新,定义定时器

    _pTimer = new QTimer(this);    _pTimer->setInterval(10);    connect(_pTimer, SIGNAL(timeout()), this, SLOT(slotRotate()));    _pTimer->start();

定时器函数,可使用startTimer函数来使用窗口自带的timerEvent定时事件

void NeHeWidget::slotRotate(){    rTri+=1;  // 增加三脚形Y轴角度    rQuad+=1; // 增加四边形X轴角度    update(); // 刷新}

扩展

        

        使三角形绕非标准轴运动

    …    // 绕 X 轴旋转四边形    glRotatef(rQuad, 1.0, 0.0, 0.0);    …

        修改后

    // 使其绕XZ平面45°轴运动,该轴通过该图形初始化原点…    …     glRotatef(rQuad, 1.0, 0.0, 1.0);    …

        关于图形初始化原点,是开始画图形之前设置的相对原点,以此点为0,0,0为坐标开始画图形,具体代码如下,glTranslatef后的glBegin和glEnd之间所花的图形,其旋转变换轴必须通过glTranslatef的相对原点

    // 清除屏幕和深度缓存    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    // 重置观察矩阵/投影矩阵    // (X坐标轴从左至右,Y坐标轴从下至上,Z坐标轴从里至外)    // OpenGL屏幕中心的坐标值是X和Y轴上的0.0点    // 中心左面的坐标值是负值,右面是正值。    // 移向屏幕顶端是正值,移向屏幕底端是负值。    // 移入屏幕深处是负值,移出屏幕则是正值。    glLoadIdentity();glLoadIdentity();    // 沿着X、Y、Z轴移动    // X轴左移1.5个单位,Y轴不动(0.0),最后移入屏幕6.0个单位    // 注意在glTranslatef(x, y, z)中当您移动的时候,    // 您并不是相对屏幕中心移动,而是相对与当前所在的屏幕位置    glTranslatef(-1.5, 0.0, -6.0);    // 让对象绕某个轴旋转 绕 Y 轴旋转三角形    glRotatef(rTri, 1.0, 1.0, 0.0);    // glBegin(GL_TRIANGLES)开始绘制三角    // 以目前所在的点为画图原点(0,0,0) 开始相对原点坐标画三角形    glBegin(GL_TRIANGLES);    glColor3f( 1.0, 0.0, 0.0 );    // 红色    // 颜色+顶点    glVertex3f( 0.0,  1.0,  0.0);  // 中上顶点    红色+中上    glColor3f( 0.0, 1.0, 0.0 );    // 绿色    glVertex3f(-1.0, -1.0,  0.0 ); // 左下顶点    绿色+左下    glColor3f( 0.0, 0.0, 1.0 );    // 蓝色    glVertex3f( 1.0, -1.0,  0.0 ); // 右下顶点    蓝色+右下    // glEnd()告诉OpenGL图形(三角)已经创建好了    // 三点间自动使用渐变填充    glEnd();

使三角形绕非标准轴运动

    …    //使其绕XY平面45°轴运动,该轴通过该图形初始化原点    glTranslatef( 1.5,  0.0,  -6.0 ); // 移动到点    // 绕 X 轴旋转四边形    glRotatef(rQuad, 1.0, 1.0, 0.0);    …

修改后

    …    //使其绕XZ平面45°轴运动,该轴通过该图形初始化原点    glTranslatef( 1.5,  0.0,  -6.0 ); // 移动到点    // 绕 X 轴旋转四边形    glRotatef(rQuad, 1.0, 0.0, 0.0);    …


原博主博客地址:http://blog.csdn.net/qq21497936
本文章博客地址:http://blog.csdn.net/qq21497936/article/details/78660326



















原创粉丝点击