原文:https://blog.csdn.net/lonely_13/article/details/78960299
最近学习QT+OpenGL,OpenGL入门之后需要在QT上使用,貌似网上只有这个代码最全,但是编译起来各种问题,非常要命。
最终再根据QT官方文档等其他资料终于将这个代码补全,喜欢的点个赞就很感谢了。
vertexshader.vert
#version 330 core
uniform mat4 matrix;
in vec4 vPosition;
in vec4 vColor;
out vec4 fColor;
void main(void)
{
fColor = vColor;
gl_Position = matrix * vPosition;
}
fragmentshader.frag
#version 330 core
in vec4 fColor;
void main(void)
{
gl_FragColor = fColor;
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtWidgets/QMainWindow>
#include "ui_mainwindow.h"
class mainwindow : public QMainWindow
{
Q_OBJECT
public:
mainwindow(QWidget *parent = 0);
~mainwindow();
private:
Ui::mainwindowClass ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "OpenGLWidget.h"
#include <QVBoxLayout>
mainwindow::mainwindow(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
OpenGLWidget* openGLWidget = new OpenGLWidget();
//为了便于让OpenGLWidget自动填充父窗口,这里为父窗口设置了一个布局
QVBoxLayout* centralLayout = new QVBoxLayout();
centralLayout->addWidget(openGLWidget);
ui.centralWidget->setLayout(centralLayout);
}
mainwindow::~mainwindow()
{
}
OpenGLWidget.h
#pragma once
#include <QWidget>
#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QOpenGLShaderProgram>
#include <QMatrix4x4>
class OpenGLWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
public:
explicit OpenGLWidget(QWidget *parent = 0);
protected:
void initializeGL();
void paintGL();
void resizeGL(int w, int h);
void initVbo();
QOpenGLShaderProgram* program;
GLuint programId;
GLint matrixLocation;
GLint vertexLocation;
GLint clorLocation;
QMatrix4x4 projection;
GLuint vVerticesLen;
GLuint triIndexLen;
GLuint colorsLen;
GLuint verVbo;
GLuint indexVbo;
GLuint colorVbo;
};
OpenGLWidget.cpp
#include "OpenGLWidget.h"
#include <iostream>
#include <string>
//三角形顶点坐标
GLfloat vertex[] = {
-0.5f, 0.0f,
0.5f, 0.0f,
0.0f, 0.5f,
};
//三角形顶点索引
GLuint triIndexs[] = { 0, 1, 2 };
//三角形顶点颜色
GLfloat colors[] = { 1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
};
OpenGLWidget::OpenGLWidget(QWidget *parent)
{
}
//OpenGLWidget::~OpenGLWidget()
//{
//}
void OpenGLWidget::initializeGL()
{
//调用内容初始化函数
initializeOpenGLFunctions();
program = new QOpenGLShaderProgram(this);
if (!program->addShaderFromSourceFile(QOpenGLShader::Vertex, "vertexshader.vert")){
return;
}
if (!program->addShaderFromSourceFile(QOpenGLShader::Fragment, "fragmentshader.frag")){
return;
}
if (!program->link()){
return;
}
if (!program->bind()){
return;
}
// 获取shaderprogram的id号,然后可以通过id号获取一些属性...
programId = program->programId();
// 从shaderprogram里面获取变量标识
matrixLocation = glGetUniformLocation(programId, "matrix");
vertexLocation = glGetAttribLocation(programId, "vPosition");
clorLocation = glGetAttribLocation(programId, "vColor");
initVbo();
}
void OpenGLWidget::resizeGL(int w, int h)
{
glViewport(0, 0, w, h);
// 模型矩阵重置
projection.setToIdentity();
// 透视投影
qreal aspect = qreal(w) / qreal(h ? h : 1);
projection.perspective(60.0f, aspect, 1.0f, 100.0f);
// 增加了模型矩阵,需要做一定偏移量,保证物体刚开始渲染出来时可以被看到!
projection.translate(0.0f, 0.0f, -2.0f);
}
void OpenGLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
// shader传入模型视图矩阵 projection可以理解为建立了一个坐标系空间,可以再这个空间内设置图形
glUniformMatrix4fv(matrixLocation, 1, GL_FALSE, projection.data());
// shader绑定并启用颜色数组buffer
glBindBuffer(GL_ARRAY_BUFFER, colorVbo);
glVertexAttribPointer(clorLocation, 4, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(clorLocation);
// 颜色值rgba,所以每四个float值作为一个颜色值,如果只是希望rgb,取三个值作为颜色值即可!
// shader绑定并启用顶点数组buffer
glBindBuffer(GL_ARRAY_BUFFER, verVbo);
glVertexAttribPointer(vertexLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(vertexLocation);
// shader绑定并顶点索引数组buffer - 索引无需启用
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVbo);
glDrawElements(GL_TRIANGLES, triIndexLen, GL_UNSIGNED_INT, 0);
// 解绑buffer、关闭启用顶点、颜色数组
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDisableVertexAttribArray(vertexLocation);
glDisableVertexAttribArray(clorLocation);
}
void OpenGLWidget::initVbo(){
// 计算获得数组长度
vVerticesLen = sizeof(vertex) / sizeof(GLfloat);
triIndexLen = sizeof(triIndexs) / sizeof(GLuint);
colorsLen = sizeof(colors) / sizeof(GLfloat);
// 初始化顶点buffer并装载数据到显存
glGenBuffers(1, &verVbo);
glBindBuffer(GL_ARRAY_BUFFER, verVbo);
glBufferData(GL_ARRAY_BUFFER, vVerticesLen * sizeof(GLfloat), vertex, GL_STATIC_DRAW);
// 初始化索引buffer并装载数据到显存
glGenBuffers(1, &indexVbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVbo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, triIndexLen * sizeof(GLuint), triIndexs, GL_STATIC_DRAW);
// 初始化颜色buffer并装载数据到显存
glGenBuffers(1, &colorVbo);
glBindBuffer(GL_ARRAY_BUFFER, colorVbo);
glBufferData(GL_ARRAY_BUFFER, colorsLen * sizeof(GLfloat), colors, GL_STATIC_DRAW);
}
main.cpp
#include "mainwindow.h"
#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
mainwindow w;
w.show();
return a.exec();
}