qt opengl

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>

//顶点着色器源码
const char *vertexShaderSource = "#version 330 core\n"
                                 "layout (location = 0) in vec3 aPos;\n"
                                 "void main()\n"
                                 "{\n"
                                 "   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
                                 "}\0";

//片段着色器源码
const char *fragmentShaderSource = "#version 330 core\n"
                                   "out vec4 FragColor;\n"
                                   "void main()\n"
                                   "{\n"
                                   "   FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
                                   "}\n\0";


Widget::Widget(QWidget *parent) :
    QOpenGLWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::initializeGL()
{
    initializeOpenGLFunctions();

    GLuint vertexShader; // 顶点着色器
    vertexShader = glCreateShader(GL_VERTEX_SHADER);//创建顶点着色器
    glShaderSource(vertexShader,1,&vertexShaderSource,NULL);// 参数二为需要编译的着色器源码数量
    glCompileShader(vertexShader);
    createShaderError(vertexShader,GL_COMPILE_STATUS,false,"Vertex Shader compiler error");

    GLuint fragmentShader;// 片段着色器
    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader,1,&fragmentShaderSource,NULL);
    glCompileShader(fragmentShader);
    createShaderError(fragmentShader,GL_COMPILE_STATUS,false,"Fragment Shader compiler error");

    m_shaderProgram = glCreateProgram();
    glAttachShader(m_shaderProgram,vertexShader);
    glAttachShader(m_shaderProgram,fragmentShader);
    glLinkProgram(m_shaderProgram);
    createShaderError(m_shaderProgram,GL_LINK_STATUS,true,"Program linking failed error");

    glUseProgram(m_shaderProgram);//激活程序对象
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
}

void Widget::resizeGL(int w, int h)
{
    //视口变换
    glViewport(0,0,(GLsizei)w,(GLsizei)h);
}

void Widget::paintGL()
{

//    glEnable(GL_DEPTH_TEST);
    //drawTriangles();
    drawRect();
}

void Widget::createShaderError(GLuint shader, GLuint flag, bool isProgram, const QString errMessage)
{
    GLint success = 0;
    GLchar error[1024] = {0};

    if (isProgram){
        glGetProgramiv(shader,flag,&success);
    }
    else {
        glGetShaderiv(shader,flag,&success);
    }

    if (success == GL_FALSE){
        if (isProgram){
            glGetProgramInfoLog(shader,sizeof(error),NULL,error);
        }
        else {
            glGetShaderInfoLog(shader,sizeof(error),NULL,error);
        }
    }
    qDebug() << errMessage << ": " << error;
}

void Widget::drawTriangles()
{
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    float vertices[] = {
        -0.5f, -0.5f, 0.0f, // left
        0.5f, -0.5f, 0.0f, // right
        0.0f,  0.5f, 0.0f  // top
    };

    unsigned int VBO, VAO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    // bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
    glBindVertexArray(VAO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    // note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    // You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
    // VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
    glBindVertexArray(0);

    glUseProgram(m_shaderProgram);
    glBindVertexArray(VAO); // seeing as we only have a single VAO there's no need to bind it every time, but we'll do so to keep things a bit more organized
    glDrawArrays(GL_TRIANGLES, 0, 3);
}

void Widget::drawRect()
{
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    float vertices[] = {
        0.5f, 0.5f, 0.0f,   // 右上
        0.5f, -0.5f, 0.0f,  // 右下
        -0.5f, 0.5f, 0.0f,  // 左上
        -0.5f, -0.5f, 0.0f  // 左下
    };
    unsigned int indices[] = {
        0,1,2,//第一个三角形
        1,2,3// 第二个三角形
    };

    unsigned int VBO, VAO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    // 1. 绑定顶点数组对象
    glBindVertexArray(VAO);
    // 2. 把我们的顶点数组复制到一个顶点缓冲中,供OpenGL使用
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    // 3. 复制我们的索引数组到一个索引缓冲中,供OpenGL使用
    unsigned int EBO;
    glGenBuffers(1,&EBO);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices),indices,GL_STATIC_DRAW);

    // 4,设置顶点指针属性
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    // You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
    // VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
    glBindVertexArray(0);

    glUseProgram(m_shaderProgram);
    glBindVertexArray(VAO);
    glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);
}




























//#include "widget.h"
//#include "ui_widget.h"

//Widget::Widget(QWidget *parent) :
//    QGLWidget(parent),
//    ui(new Ui::Widget)
//{
//    ui->setupUi(this);
//}

//Widget::~Widget()
//{
//    delete ui;
//}

//void Widget::initializeGL()
//{
//    //设置widget的坐标和尺寸
//    setGeometry(300, 150, 500, 500);
//    //设置清除时颜色
//    glClearColor(0.0, 0.0, 0.0, 0);
//}

//void Widget::resizeGL(int w, int h)
//{
//    //视口变换
//    glViewport(0,0,(GLsizei)w,(GLsizei)h);
//    //投影变换
//    glMatrixMode(GL_PROJECTION);
//    glLoadIdentity();
//    gluPerspective(40.0,(GLdouble)w/(GLdouble)h,0.1,10000.0);
//    //视图变换
//    glMatrixMode(GL_MODELVIEW);
//    glLoadIdentity();
//    gluLookAt(0.0,0.0,15.0,0.0,0.0,0.0,0.0,1.0,0.0);
//}

//void Widget::paintGL()
//{
//    //清屏
//    glClear(GL_COLOR_BUFFER_BIT);
//    //绘制七彩三角形
//    glBegin(GL_TRIANGLES);
//    glColor3f(1.0,0.0,0.0);
//    glVertex3f(-2,0,0);
//    glColor3f(0.0,1.0,0.0);
//    glVertex3f(2,0,0);
//    glColor3f(0.0,0.0,1.0);
//    glVertex3f(0,4,0);
//    glEnd();
//    glFlush();
//}
View Code
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QOpenGLWidget>
#include <QOpenGLFunctions_3_0>

namespace Ui {
class Widget;
}

class Widget : public QOpenGLWidget,protected QOpenGLFunctions_3_0
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

    void initializeGL();
    void resizeGL(int w,int h);
    void paintGL();
private:
    void createShaderError(GLuint shader,GLuint flag,bool isProgram,const QString errMessage);
    void drawTriangles();
    void drawRect();
private:
    GLuint m_shaderProgram;//着色器程序对象
private:
    Ui::Widget *ui;
};

#endif // WIDGET_H









//#ifndef WIDGET_H
//#define WIDGET_H

//#include <QWidget>
//#include <QtOpenGL/qgl.h>
//#include <GL/gl.h>
//#include <GL/glu.h>
//#include <QOpenGLWidget>
//#include <QOpenGLFunctions_3_0>

//namespace Ui {
//class Widget;
//}

//class Widget : public QGLWidget
//{
//    Q_OBJECT

//public:
//    explicit Widget(QWidget *parent = 0);
//    ~Widget();

//    void initializeGL();
//    void resizeGL(int w,int h);
//    void paintGL();

//private:
//    Ui::Widget *ui;
//};

//#endif // WIDGET_H
View Code

猜你喜欢

转载自www.cnblogs.com/xiangtingshen/p/12061188.html