整理 qt opengl,自己的基础框架 —— 绘制一个彩色三角形

将代码放到这里,以便日后使用。隔段时间后再来看opengl,就会发现突然无从下手,但那时却是可以简简单单地、轻轻松松地写出这么个程序。基于此,还是给自己留下完整的东西,基础框架,省得日后忘记了还得重新看、重新写。


.pro:

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. QT       += core gui  
  2.   
  3. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets  
  4.   
  5. TARGET = draw  
  6. TEMPLATE = app  
  7.   
  8. SOURCES += \  
  9.     main.cpp \  
  10.     glwigdet.cpp \  
  11.     drawtriangle.cpp  
  12.   
  13. HEADERS += \  
  14.     glwigdet.h \  
  15.     drawtriangle.h  
  16.   
  17. RESOURCES += \  
  18.     shaders.qrc  
 

main.cpp:

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include <QApplication>  
  2. #include <QSurfaceFormat>  
  3.   
  4. #include "drawtriangle.h"  
  5.   
  6. int main(int argc, char *argv[])  
  7. {  
  8.     QApplication app(argc, argv);  
  9.   
  10.     QSurfaceFormat format;  
  11.     format.setDepthBufferSize(24);  
  12.     QSurfaceFormat::setDefaultFormat(format);  
  13.   
  14.     DrawTriangle drawT;  
  15.     drawT.show();  
  16.   
  17.     return app.exec();  
  18. }  

glwidget.h:

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #ifndef GLWIGDET_H  
  2. #define GLWIGDET_H  
  3.   
  4. #include <QOpenGLWidget>  
  5. #include <QOpenGLFunctions>  
  6. #include <QOpenGLShaderProgram>  
  7. #include <QOpenGLBuffer>  
  8.   
  9. #include <QMouseEvent>  
  10. #include <QTimerEvent>  
  11. #include <QKeyEvent>  
  12. #include <QBasicTimer>  
  13. #include <QVector3D>  
  14. #include <QVector2D>  
  15.   
  16. /* 从OpenGL 3开始,编程模式被分为3种:  
  17.  * 1.兼容模式:即传统的方式  
  18.  * 2.核心模式:完全新式纯可编程流水线模式,但兼容废弃特性。(注:API不兼容旧的)  
  19.  * 3.核心向前兼容模式:完全不兼容废弃特性,其它同核心模式。(主要表现在线宽、线调色板这一类,其它同核心模式)  
  20.  *******************************************************************************************/  
  21.   
  22. class GLWigdet : public QOpenGLWidget, protected QOpenGLFunctions  
  23. {  
  24.     Q_OBJECT  
  25. public:  
  26.     GLWigdet(QWidget *parent = 0);  
  27.   
  28. protected:  
  29.     void mousePressEvent(QMouseEvent *e) Q_DECL_OVERRIDE;  
  30.     void mouseReleaseEvent(QMouseEvent *e) Q_DECL_OVERRIDE;  
  31.     void timerEvent(QTimerEvent *e) Q_DECL_OVERRIDE;  
  32.     void keyPressEvent(QKeyEvent *e) Q_DECL_OVERRIDE;  
  33.   
  34.     void initializeGL() Q_DECL_OVERRIDE;  
  35.     void resizeGL(int w, int h) Q_DECL_OVERRIDE;  
  36.     void paintGL() Q_DECL_OVERRIDE;  
  37.   
  38.     void initShaders();  
  39.   
  40.     virtual void do_init() {}  
  41.     virtual void do_paint() {}  
  42.     virtual void do_resize() {}  
  43.   
  44. protected:  
  45.     QOpenGLShaderProgram program;  
  46.     int a_position;  
  47.   
  48. private:  
  49.     QBasicTimer timer;  
  50.     QVector2D mousePressPosition;  
  51.     QVector3D rotationAxis;  
  52.     qreal angularSpeed;  
  53.     QQuaternion rotation;  
  54.     QMatrix4x4 m_proj;   /* 投影矩阵 */  
  55. };  
  56.   
  57. #endif // GLWIGDET_H  

glwidget.cpp:

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include "glwigdet.h"  
  2.   
  3. GLWigdet::GLWigdet(QWidget *parent)  
  4.     : QOpenGLWidget(parent)  
  5. {  
  6.     setWindowTitle("opengl");  
  7.     resize(1280, 720);  
  8.   
  9.     angularSpeed = 0;  
  10. }  
  11.   
  12. void GLWigdet::initializeGL()  
  13. {  
  14.     /* 初始化函数,使得函数可以使用 */  
  15.     initializeOpenGLFunctions();  
  16.   
  17.     initShaders();  
  18.   
  19.     a_position = program.attributeLocation("a_position");  
  20.   
  21.     do_init();  
  22.   
  23.     // Use QBasicTimer because its faster than QTimer  
  24.     timer.start(12, this);  
  25. }  
  26.   
  27. void GLWigdet::initShaders()  
  28. {  
  29.     // Compile vertex shader  
  30.     if (!program.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shaders/vshader.glsl"))  
  31.         close();  
  32.   
  33.     // Compile fragment shader  
  34.     if (!program.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shaders/fshader.glsl"))  
  35.         close();  
  36.   
  37.     // Link shader pipeline  
  38.     if (!program.link())  
  39.         close();  
  40.   
  41.     // Bind shader pipeline for use  
  42.     if (!program.bind())  
  43.         close();  
  44. }  
  45.   
  46. void GLWigdet::paintGL()  
  47. {  
  48.     glClear(GL_COLOR_BUFFER_BIT);  
  49.     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);  
  50.   
  51.     glClear(GL_DEPTH_BUFFER_BIT);  
  52.     glEnable(GL_DEPTH_TEST);  
  53.   
  54.     // Calculate model view transformation  
  55.     QMatrix4x4 matrix;  
  56.     matrix.translate(0.0, 0.0, -5.0);  
  57.     matrix.rotate(rotation);  
  58.   
  59.     // Set modelview-projection matrix  
  60.     int mvp_matrix = program.uniformLocation("mvp_matrix");  
  61.     program.setUniformValue(mvp_matrix, m_proj * matrix);  
  62.   
  63.     do_paint();  
  64. }  
  65.   
  66. void GLWigdet::resizeGL(int w, int h)  
  67. {  
  68.     // Calculate aspect ratio  
  69.     qreal aspect = qreal(w) / qreal(h ? h : 1);  
  70.   
  71.     // Set near plane to 3.0, far plane to 7.0, field of view 45 degrees  
  72.     const qreal zNear = 3.0, zFar = 7.0, fov = 45.0;  
  73.   
  74.     // Reset projection  
  75.     m_proj.setToIdentity();  
  76.   
  77.     // Set perspective projection  
  78.     m_proj.perspective(fov, aspect, zNear, zFar);  
  79. }  
  80.   
  81. void GLWigdet::keyPressEvent(QKeyEvent *kev)  
  82. {  
  83.     if(kev->key() == Qt::Key_Escape) {  
  84.         close();  
  85.     } else {  
  86.         QOpenGLWidget::keyPressEvent(kev);  
  87.     }  
  88. }  
  89.   
  90. void GLWigdet::mousePressEvent(QMouseEvent *e)  
  91. {  
  92.     // Save mouse press position  
  93.     mousePressPosition = QVector2D(e->localPos());  
  94. }  
  95.   
  96. void GLWigdet::mouseReleaseEvent(QMouseEvent *e)  
  97. {  
  98.     // Mouse release position - mouse press position  
  99.     QVector2D diff = QVector2D(e->localPos()) - mousePressPosition;  
  100.   
  101.     // Rotation axis is perpendicular to the mouse position difference  
  102.     // vector  
  103.     QVector3D n = QVector3D(diff.y(), diff.x(), 0.0).normalized();  
  104.   
  105.     // Accelerate angular speed relative to the length of the mouse sweep  
  106.     qreal acc = diff.length() / 100.0;  
  107.   
  108.     // Calculate new rotation axis as weighted sum  
  109.     rotationAxis = (rotationAxis * angularSpeed + n * acc).normalized();  
  110.   
  111.     // Increase angular speed  
  112.     angularSpeed += acc;  
  113. }  
  114.   
  115. void GLWigdet::timerEvent(QTimerEvent *)  
  116. {  
  117.     // Decrease angular speed (friction)  
  118.     angularSpeed *= 0.99;  
  119.   
  120.     // Stop rotation when speed goes below threshold  
  121.     if (angularSpeed < 0.01) {  
  122.         angularSpeed = 0.0;  
  123.     } else {  
  124.         // Update rotation  
  125.         rotation = QQuaternion::fromAxisAndAngle(rotationAxis, angularSpeed) * rotation;  
  126.   
  127.         // Request an update  
  128.         update();  
  129.     }  
  130. }  

drawtriangle.h:

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #ifndef DRAWTRIANGLE_H  
  2. #define DRAWTRIANGLE_H  
  3.   
  4. #include "glwigdet.h"  
  5.   
  6. class DrawTriangle : public GLWigdet  
  7. {  
  8. public:  
  9.     DrawTriangle(QWidget *parent = 0);  
  10.   
  11. protected:  
  12.     void do_init() Q_DECL_OVERRIDE;  
  13.     void do_paint() Q_DECL_OVERRIDE;  
  14.   
  15. private:  
  16.     int num;  
  17.     int mvp_matrix;  
  18. };  
  19.   
  20. #endif // DRAWTRIANGLE_H  

drawtriangle.cpp

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include "drawtriangle.h"  
  2.   
  3. DrawTriangle::DrawTriangle(QWidget *parent)  
  4.     : GLWigdet(parent), num(0)  
  5. {  
  6.     setWindowTitle("绘制三角形");  
  7. }  
  8.   
  9. void DrawTriangle::do_init()  
  10. {  
  11. }  
  12.   
  13. void DrawTriangle::do_paint()  
  14. {  
  15.     /* 1.5 为使用项目对象去渲染,需要绑定 */  
  16.     program.bind();  
  17.   
  18.     /* 2.3 三角形顶点的坐标 */  
  19.     GLfloat vVertices[] = {  
  20.         0.0f, 0.5f, 0.0f,  
  21.         -0.5f, -0.5f, 0.0f,  
  22.         0.5f, -0.5f, 0.0f  
  23.     };  
  24.   
  25.     /* 2.4 Load the vertex data */  
  26.     glVertexAttribPointer(a_position, 3, GL_FLOAT, GL_FALSE, 0, vVertices);  
  27.     glEnableVertexAttribArray(a_position);  
  28.   
  29.     /* 三角形 */  
  30.     glDrawArrays(GL_TRIANGLES, 0, 3);  
  31.   
  32.     glFlush();  
  33. }  
       shaders.qrc资源包含两个着色器代码: vshader.glsl、fshader.glsl

vshader.glsl:

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #version 130  
  2.   
  3. uniform mat4 mvp_matrix;  
  4. attribute highp vec4 a_position;  
  5. //out  
  6. varying lowp vec4 v_color;  
  7.   
  8. void main() {  
  9.     gl_Position = mvp_matrix * a_position;  
  10.     v_color = a_position;  
  11. }  
fshader.glsl:

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #version 130  
  2.   
  3. varying lowp vec4 v_color;  
  4.   
  5. out highp vec4 fragColor;  
  6.   
  7. void main() {  
  8.     fragColor = v_color;  
  9. }  

       运行结果:


      鼠标拖动让其旋转的代码是拷贝官方cube这个例子的。由于这样代码看上去显得繁多,所以做一个基础类,后面具体绘制什么就继承这个类。


      继承后的子类肯定要做些东西,所以预留do_xxx接口。

      由于子类很有可能需要使用program,因此暂时作为protected成员。



FROM:  http://blog.csdn.net/fu851523125/article/details/51626489

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值