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

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

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


《OpenGL学习笔记》系列博客目录地址:http://blog.csdn.net/qq21497936/article/category/7315532


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

        001.gif

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


OpenGL坐标系理解

图片.png

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

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


OpenGL基本窗口建立

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

图片.png


       创建完成后,首先就是要该窗口继承的基类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(); // 刷新
}

扩展

        02.gif

       使三角形绕非标准轴运动

    // 绕 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



相关文章
OpenGL学习笔记(二):OpenGL语法、渲染管线以及具体实现过程详解
OpenGL学习笔记(二):OpenGL语法、渲染管线以及具体实现过程详解
OpenGL学习笔记(二):OpenGL语法、渲染管线以及具体实现过程详解
|
缓存 索引
OpenGL学习笔记(十三):将纹理贴图应用到四边形上,对VAO/VBO/EBO/纹理/着色器的使用方式进行总结
OpenGL学习笔记(十三):将纹理贴图应用到四边形上,对VAO/VBO/EBO/纹理/着色器的使用方式进行总结
OpenGL学习笔记(十三):将纹理贴图应用到四边形上,对VAO/VBO/EBO/纹理/着色器的使用方式进行总结
|
存储 缓存 C++
OpenGL学习笔记(十二):纹理的使用
OpenGL学习笔记(十二):纹理的使用
OpenGL学习笔记(十二):纹理的使用
|
编译器 C语言 C++
OpenGL学习笔记(十一):封装自己的着色器类
OpenGL学习笔记(十一):封装自己的着色器类
OpenGL学习笔记(十一):封装自己的着色器类
|
小程序 编译器 C语言
OpenGL学习笔记(十):深入学习和理解着色器
OpenGL学习笔记(十):深入学习和理解着色器
OpenGL学习笔记(十):深入学习和理解着色器
|
缓存 索引
OpenGL学习笔记(九):索引缓冲器(EBO /IBE)的理解与使用,引入线框/填充模式
OpenGL学习笔记(九):索引缓冲器(EBO /IBE)的理解与使用,引入线框/填充模式
OpenGL学习笔记(九):索引缓冲器(EBO /IBE)的理解与使用,引入线框/填充模式
|
存储 索引
OpenGL学习笔记(八):进一步理解VAO、VBO和SHADER,并使用VAO、VBO和SHADER绘制一个三角形 下
OpenGL学习笔记(八):进一步理解VAO、VBO和SHADER,并使用VAO、VBO和SHADER绘制一个三角形
OpenGL学习笔记(八):进一步理解VAO、VBO和SHADER,并使用VAO、VBO和SHADER绘制一个三角形 下
|
存储 C语言 C++
OpenGL学习笔记(八):进一步理解VAO、VBO和SHADER,并使用VAO、VBO和SHADER绘制一个三角形 上
OpenGL学习笔记(八):进一步理解VAO、VBO和SHADER,并使用VAO、VBO和SHADER绘制一个三角形
OpenGL学习笔记(八):进一步理解VAO、VBO和SHADER,并使用VAO、VBO和SHADER绘制一个三角形 上
|
IDE 开发工具 C语言
OpenGL学习笔记(七):创建第一个Qt5.9.3 OpenGL工程模版(与平台无关)
OpenGL学习笔记(七):创建第一个Qt5.9.3 OpenGL工程模版(与平台无关)
OpenGL学习笔记(七):创建第一个Qt5.9.3 OpenGL工程模版(与平台无关)
|
IDE 编译器 开发工具
OpenGL学习笔记(六):创建第一个VS2015 OpenGL工程模板(与平台无关)
OpenGL学习笔记(六):创建第一个VS2015 OpenGL工程模板(与平台无关)
OpenGL学习笔记(六):创建第一个VS2015 OpenGL工程模板(与平台无关)