[Qt和GLSL的笔记1] 程序的基本结构

来源:互联网 发布:乌克丽丽调音器软件 编辑:程序博客网 时间:2024/05/18 07:10

时间:2017年4月21日(大三下学期)

作者:RyuZhihao123(Northwest A&F University,985/211)


写在前面:

       最近开始尝试在Qt下使用GLSL进行编程。在这近2年的Qt使用中,着实对Qt便捷的ui框架感到震撼。不管是QML、QSS、还是对Python的支持都非常完美,为我们做应用开发提供了太多的便利。

      众所周知,Qt5对opengl的支持非常强大。,一直想要尝试杂Qt下做GLSL的开发,但是不幸的是,相关的资料太少(几乎没有)。虽然Qt给出了几个examples,但是我拿了几天的时间才真正理解其基本结构(不会是我笨吧?_(:3 」∠)_)。

      于是呢,我打算整理几篇关于Qt5和GLSL的教程。大概涉及Qt5和GLSL的程序基本框架、GLSL的基本知识等等。


Qt和GLSL开发1:使用QGLShaderProgram的基本结构

任务:

         可能在正式踏入Qt和GLSL之前,很多人都被程序的基本结构挡住了,所以在第一篇教程里,我不打算介绍过多的关于qt和GLSL的基本知识。首先帮大家搭建起一个Qt下使用QGLShaderProgram类的基本框架,我们之后的所有工作,大抵是在此基础上做出修改。

代码的下载链接:

             http://download.csdn.net/detail/mahabharata_/9821155

程序的执行结果为一个简单的着色小球:



       首先,建立一个Qt Widgets Application,默认继承自QWidget。我习惯这样建立Qt中的OpenGL程序:先建立继承QWidget的项目,然后手动修改为集成自QGLWidget。使用这种方法的话,大家可以省去编辑.pro和main.cpp的功夫。(当然也可以建立一个空项目,自己从头创建文件也可以~

      不过需要注意的是:

      1. 为了在Qt中使用opengl,我们需要先在.pro文件中添加:

QT       += opengl
      其实就是VS中使用opengl需要先链接一堆.lib文件的工作,在Qt中比较方便而已。

      2. 如果是使用继承自QWidget,然后自己修改为QGLWidget的方法的话,需要删除自动创建的关于ui的文档和代码。具体可以参考我给出的下载链接,或者下面的代码。这个工作非常简单。


最终的程序的文档结构如下:


       在上图中出现的两个shader的添加方式为:在工程名上右键,选择“添加新文件”,在弹出的“新建文件”对话框中,选择GLSL - 顶点着色器/片段着色器。



下面给出一下程序中各个文档的代码

1. 顶点着色器vsrc.vert

varying vec4 v_position;void main(void){       gl_Position = gl_ProjectionMatrix*gl_ModelViewMatrix * gl_Vertex;       v_position = gl_Position;}
2. 片段着色器fsrc.frag

varying vec4 v_position;void main(void){    // 默认光照的颜色    float r = 1.0f;    float g = 0.5f;    float b = 0.5f;    float length = v_position.x * v_position.x + v_position.y * v_position.y + v_position.z*v_position.z; // 距离的平方    float rate = 13000.0f / length; // 比值    gl_FragColor = vec4(rate * r, rate * g, rate * b, 1.0f); // glFragColor表示这个点的最终颜色}
3. widget.h(OpenGL的widget窗口)

#ifndef WIDGET_H#define WIDGET_H#include <QWidget>#include <QtOpenGL/QGLWidget>#include <GL/glu.h>#include <QGLShaderProgram>#include <QGLShader>class Widget : public QGLWidget{    Q_OBJECTpublic:    explicit Widget(QWidget *parent = 0);    ~Widget();protected:    void initializeGL();    void resizeGL(int w, int h);    void paintGL();private:    // 着色器程序 shader program;    QGLShaderProgram program;    // 初始化着色器 init shader;    void makeShader();};#endif // WIDGET_H

4. widget.cpp(包含最关键的opengl代码)

#include "widget.h"Widget::Widget(QWidget *parent) :    QGLWidget(parent){}void Widget::initializeGL(){    glClearColor(0.0,0.0,0.0,1.0);    glShadeModel(GL_SMOOTH);    glEnable(GL_DEPTH_TEST);    glEnable(GL_COLOR_MATERIAL);    makeShader();   // 初始化shader}void Widget::resizeGL(int w, int h){    glViewport(0,0,(GLsizei)w,(GLsizei)h);    glMatrixMode(GL_PROJECTION);    glLoadIdentity();    gluPerspective(45.0,(GLdouble)w/(GLdouble)h,0.0001,1000.0);}void Widget::paintGL(){    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    glMatrixMode(GL_MODELVIEW);    glLoadIdentity();    gluLookAt(0.0,50.0,100.0,0.0,0.0,0.0,0.0,1.0,0.0);    // 利用二次曲面绘制一个球    static GLUquadric* qobj = NULL;    if(qobj == NULL)        qobj = gluNewQuadric();    gluSphere(qobj,15.0,30.0,30.0);}void Widget::makeShader(){    // shader文件的路径(路径自行修改)    static const QString vertFile = "C:/Qt/Qt5.2.0/Tools/QtCreator/bin/untitled/vsrc.vert";    static const QString fragFile = "C:/Qt/Qt5.2.0/Tools/QtCreator/bin/untitled/fsrc.frag";    // shader program加载两个shader    program.addShaderFromSourceFile(QGLShader::Vertex,vertFile);    program.addShaderFromSourceFile(QGLShader::Fragment,fragFile);    program.link();  // 链接通过addShader添加的着色器    program.bind();  // 使该shader真正启动(绑定到当前的opengl上下文中)}Widget::~Widget(){}
5. main.cpp

#include "widget.h"#include <QApplication>int main(int argc, char *argv[]){    QApplication a(argc, argv);    Widget w;    w.show();    return a.exec();}
6. 项目配置文件untitled.pro

#-------------------------------------------------## Project created by QtCreator 2017-04-18T15:05:31##-------------------------------------------------QT       += core guiQT       += openglgreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsTARGET = untitledTEMPLATE = appSOURCES += main.cpp\        widget.cppHEADERS  += widget.hFORMS    +=OTHER_FILES += \    vsrc.vert \    fsrc.frag


        到现在,我们已经可以搭建出一个使用QGLShaderProgram的GLSL程序,不知道大家能否成功执行出预期的结果。这里,仅仅给出了一个程序的基本框架,虽然只是第一步,但是我们却可以在此基础上进行其他更多的操作~

        关于Qt开发modern opengl,Qt 本身提供了一个例子,大家可以在examples里面看一下,有很多非常惊艳的demo。

       To be continued ~ (。・`ω´・)



             


3 0
原创粉丝点击