Qt5.1 And Modern OpenGL_C/C++_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > C/C++ > Qt5.1 And Modern OpenGL

Qt5.1 And Modern OpenGL

 2013/7/17 10:13:16  schi  程序员俱乐部  我要评论(0)
  • 摘要:Ibeenlearningmodernopenglforawhile.IreallywanttouseQtwithopengl.ButtheQt4.7.x'sopenglwasbrokenatwindows.(Idon'tknowiftheyfixitatQt4.8.x.Butthepythonbindingworks,bothPyQtandPySide).SoIhavetowaitingforQt5.Qt5'sopenglwasredesigned
  • 标签:
I been learning modern opengl for a while. I really want to use Qt with opengl. But the Qt4.7.x's opengl was broken at windows.(I don't know if they fix it at Qt4.8.x. But the python binding works, both PyQt and PySide). So I have to waiting for Qt5. Qt5's opengl was redesigned, all new opengl class are in QtGui module now. It's quite different with Qt4. Here's example how to use OpenGL3.3 with Qt5.1. The new opengl in Qt5 has prefix QOpenGL*. I want to learn the pure opengl functions. So I will use gl* most of the time.

myglwindow.h
#ifndef MyGLWindow_H
#define MyGLWindow_H

#include <QWindow>
// for loading shaders and compile shaderprogram 
#include <QOpenGLShaderProgram>
// load opengl functions, if you use different version
// change the number to your version number
#include <QOpenGLFunctions_3_3_Core>

class MyGLWindow : public QWindow, protected QOpenGLFunctions_3_3_Core
{
    Q_OBJECT

public:
    MyGLWindow(QScreen *screen=0);
    ~MyGLWindow();

    // render function
    void render();
    // do all the initialize before render
    void initialize();

protected:
    void exposeEvent(QExposeEvent *event);
    void resizeEvent(QResizeEvent *event);

private:
    // opengl contex obj
    QOpenGLContext *m_context;
    // shader program obj
    QOpenGLShaderProgram *m_program;
    GLuint VAO;  // Vertex Array Object
    GLuint VBO;  // Vertex Buffer Object
};

#endif // MyGLWindow_H


myglwindow.cpp
#include “myglwindow.h"

MyGLWindow::MyGLWindow(QScreen *screen=0)
    : QWindow(screen)
{
    // Tell Qt this window is use for OpenGL
    setSurfaceType(OpenGLSurface);

    // setup opengl context's format
    // like opengl's version and profile
    QSurfaceFormat format;
    format.setMajorVersion(3);
    format.setMinorVersion(3);
    format.setProfile(QSurfaceFormat::CoreProfile);
    setFormat(format);

    // make sure the format was use by the window
    // you don't need to call it directly, as it 
    // will be implicitly called by show()
    create();

    // create opengl context
    m_context = new QOpenGLContext;
    m_context->setFormat(format);
    m_context->create();
    // tell the window to use it
    m_context->makeCurrent(this);

    // load opengl functions
    initializeOpenGLFunctions();

    // 
    initialize();
}

MyGLWindow::~MyGLWindow()
{
}

void MyGLWindow::render()
{
    // we need to make sure the context is current
    m_context->makeCurrent(this);

    // clear screen color to black 
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    // active shader program
    glUseProgram(m_program->programId());

    // bind Vertex Array Object
    glBindVertexArray(VAO);

    // draw triangle
    glDrawArrays(GL_TRIANGLES, 0, 3);

    // bind Vertex Array to 0
    glBindVertexArray(0);
    glUseProgram(0);

    m_context->swapBuffers(this);
}

void MyGLWindow::initialize()
{
    // create shader program
    m_program = new QOpenGLShaderProgram(m_context);
    // load vertex shader
    m_program->addShaderFromSourceFile(QOpenGLShader::Vertex, "vertexColors.vert");
    // load fragment shader
    m_program->addShaderFromSourceFile(QOpenGLShader::Fragment, "vertexColors.frag");
    m_program->link(); // compile and link shader program

    const float vertexData[] = {
        // x    y     z    w
        0.0f, 0.5f, 0.0f, 1.0f, 
        0.5f, -0.366f, 0.0f, 1.0f, 
        -0.5f, -0.366f, 0.0f, 1.0f, 

        // R    G     B    A
        1.0f, 0.0f, 0.0f, 1.0f, 
        0.0f, 1.0f, 0.0f, 1.0f, 
        0.0f, 0.0f, 1.0f, 1.0f, 
    };

    // create Vertex Buffer Object
    glGenBuffers(1, &VBO);
    // bind it to the GL_ARRAY_BUFFER
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    // copy data to GPU
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
    // bind the GL_ARRAY_BUFFER to 0
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    // create Vertex Array Object
    glGenVertexArrays(1, &VAO);
    // bind it
    glBindVertexArray(VAO);
    
    // bind VBO to GL_ARRAY_BUFFER
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    // enable vertex array
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    // setup the data format
    // this will tell VAO that the vertex array 0 is something like
    // [[0.0f, 0.5f, 0.0f, 1.0f], [0.5f, -0.366f, 0.0f, 1.0f,], [-0.5f, -0.366f, 0.0f, 1.0f]]
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
    // the last parameter is a pointer
    // specifies the offset of the first component of the vertexData[]
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)48);

    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

void MyGLWindow::exposeEvent(QExposeEvent *event)
{
    if(isExpose())
        render();
}

void MyGLWindow::resizeEvent(QResizeEvent *event)
{
    // tell opengl to resize
    glViewport(0, 0, width(), height());
    if(isExpose())
        render();
}


main.cpp
#include <QApplication>
#include "myglwindow.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MyGLWindow w;
    w.resize(640, 480);
    w.show();
    return a.exec();
}



vertex shader
vertexColors.vert
#version 330

layout(location=0) in vec4 position;
layout(location=1) int vec4 color;

out vec4 theColor;

void main()
{
    gl_Position = position;
    theColor = color;
}


Fragment shader
vertexColors.frag
#version 330

in vec4 theColor;

out vec4 outColor;

void main()
{
    outColor = theColor;
}
  • 相关文章
发表评论
用户名: 匿名