我这是使用QT写的
目录
[1 核心源码](#1 核心源码)
[1.1 MyOpenGL头文件](#1.1 MyOpenGL头文件)
[1.2 MyOpenGL实现文件](#1.2 MyOpenGL实现文件)
[1.3 cmake文件](#1.3 cmake文件)
[2 QOpenGLWidget提升为自定义MyOpenglWidget](#2 QOpenGLWidget提升为自定义MyOpenglWidget)
[2.1 提升为自定义的MyOpenGL](#2.1 提升为自定义的MyOpenGL)
[2.2 设置setCentralWidget为MyOpenGL](#2.2 设置setCentralWidget为MyOpenGL)
效果

1 核心源码
1.1 MyOpenGL头文件
cpp
#ifndef MYOPENGL_H
#define MYOPENGL_H
// 继承字OpenGLWidget
#include <QOpenGLWidget>
// 使用3.3的版本
#include <QOpenGLFunctions_3_3_Core>
// Qt的shaderProgram对象
#include <QOpenGLShaderProgram>
class MyOpenGL : public QOpenGLWidget,protected QOpenGLFunctions_3_3_Core
{
Q_OBJECT
public:
explicit MyOpenGL(QWidget* parent = nullptr);
~MyOpenGL();
protected:
virtual void initializeGL();
virtual void resizeGL(int w, int h);
virtual void paintGL();
private:
unsigned int VAO,VBO,EBO;
// shader程序对象
QOpenGLShaderProgram* m_shaderProgram;
GLuint native_shaderProgram;
void setupGeometry();
void initNativeShader();
void initQtShader();
};
#endif // MYOPENGL_H
1.2 MyOpenGL实现文件
cpp
#include "myopengl.h"
MyOpenGL::MyOpenGL(QWidget *parent)
:QOpenGLWidget(parent)
{
qDebug()<< "inited";
}
MyOpenGL::~MyOpenGL()
{
// 切换到当前widget的上下文
makeCurrent();
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1,&VBO);
glDeleteBuffers(1, &EBO);
glDeleteProgram(native_shaderProgram);
doneCurrent();
}
void MyOpenGL::initializeGL()
{
// 获取OpenGL的函数指针
this->initializeOpenGLFunctions();
// 1 opengl原生方法初始化Shader程序
initNativeShader();
// initQtShader();
// 2 初始化物体信息
setupGeometry();
}
void MyOpenGL::resizeGL(int w, int h)
{
}
void MyOpenGL::setupGeometry(){
float vertices[24] = {
// 位置 颜色
0.0f, 0.5f, 0.0f, 1.0f,0.0f,0.0f, //上 红
-0.5f, -0.0f, 0.0f, 0.0f,1.0f,0.0f, //左下 绿
0.5f, 0.0f, 0.0f, 0.0f,0.0f,1.0f, //右下 蓝
0.0f, -0.5f, 0.0f, 1.0f,1.0f,0.0f //右下 橙色
};
// 每3个点读一次
unsigned int indexes[6] = {0,1,2,1,2,3};
glGenVertexArrays(1,&VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
// 激活定点数组配置,开始记录定点属性
glBindVertexArray(VAO);
// 绑定VBO 包含数据
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices,GL_STATIC_DRAW);
// EBO 缓冲
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indexes),indexes,GL_STATIC_DRAW);
// 参数1:索引
// 参数2:几个数据
// 参数3:数据类型
// 参数4:是否归一化,如果是0-255需要转为0-1
// 参数5:步长
// 参数6:偏移量
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,6 * sizeof(float),(void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,6 * sizeof(float),(void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
// 解绑VBO
glBindBuffer(GL_ARRAY_BUFFER,0);
// 解绑VAO 不需要解绑EBO,当VAO解绑时自动解绑
glBindVertexArray(0);
}
void MyOpenGL::paintGL()
{
// 只在200*200的范围内绘制
glViewport(0,0,200,200);
// 清理屏幕
glClearColor(0.1,0.2,0.3,1);
glClear(GL_COLOR_BUFFER_BIT);
// 使用shader程序
glUseProgram(native_shaderProgram); //原生写法
// m_shaderProgram->bind(); // qt 的写法
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,nullptr);
glBindVertexArray(0);
glUseProgram(0);
}
void MyOpenGL::initNativeShader(){
const char* vSrc = R"(
#version 330 core
layout(location=0) in vec3 aPos;
layout(location=1) in vec3 aColor;
out vec3 ourColor;
void main(){
gl_Position = vec4(aPos,1.0);
ourColor = aColor;
}
)";
const char* fSrc = R"(
#version 330 core
in vec3 ourColor;
out vec4 FragColor;
void main(){
FragColor = vec4(ourColor,1.0);
}
)";
// 创建shader,加载源码,编译
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader,1,&vSrc,nullptr);
glCompileShader(vertexShader);
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader,1,&fSrc,nullptr);
glCompileShader(fragmentShader);
// 创建程序,绑定shader,链接为GPU程序
native_shaderProgram = glCreateProgram();
glAttachShader(native_shaderProgram,vertexShader);
glAttachShader(native_shaderProgram,fragmentShader);
glLinkProgram(native_shaderProgram);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
}
void MyOpenGL::initQtShader()
{
const char* vSrc = R"(
#version 330 core
layout(location=0) in vec3 aPos;
layout(location=1) in vec3 aColor;
out vec3 ourColor;
void main(){
gl_Position = vec4(aPos,1.0);
ourColor = aColor;
}
)";
const char* fSrc = R"(
#version 330 core
in vec3 ourColor;
out vec4 FragColor;
void main(){
FragColor = vec4(ourColor,1.0);
}
)";
m_shaderProgram = new QOpenGLShaderProgram();
QOpenGLShader * vertexShader = new QOpenGLShader(QOpenGLShader::Vertex);
vertexShader->compileSourceCode(vSrc);
QOpenGLShader * fragmentShader = new QOpenGLShader(QOpenGLShader::Fragment);
fragmentShader->compileSourceCode(fSrc);
// 对应原生的attach
m_shaderProgram->addShader(vertexShader);
m_shaderProgram->addShader(fragmentShader);
// 将编译完成的着色器目标对象进行链接,生成完整GPU着色器程序
m_shaderProgram->link();
}
1.3 cmake文件
cpp
cmake_minimum_required(VERSION 3.19)
project(python LANGUAGES CXX)
find_package(Qt6 6.5 REQUIRED COMPONENTS Core Widgets)
# 查找组件
find_package(Qt6 REQUIRED COMPONENTS OpenGLWidgets)
qt_standard_project_setup()
qt_add_executable(python
WIN32 MACOSX_BUNDLE
main.cpp
mainwindow.cpp
mainwindow.h
mainwindow.ui
resources.qrc
myopengl.h myopengl.cpp
)
target_link_libraries(python
PRIVATE
Qt::Core
Qt::Widgets
)
# 自定义函数的头文件查找地址
target_include_directories(python PRIVATE ${CMAKE_SOURCE_DIR})
# 链接库
target_link_libraries(python PRIVATE Qt6::OpenGLWidgets)
install(TARGETS python
BUNDLE DESTINATION .
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
qt_generate_deploy_app_script(
TARGET python
OUTPUT_SCRIPT deploy_script
NO_UNSUPPORTED_PLATFORM_ERROR
)
install(SCRIPT ${deploy_script})
2 QOpenGLWidget提升为自定义MyOpenglWidget
2.1 提升为自定义的MyOpenGL

2.2 设置setCentralWidget为MyOpenGL
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
setCentralWidget(ui->openGLWidget);
}
MainWindow::~MainWindow()
{
delete ui;
}