Create your Gitee Account
Explore and code with more than 12 million developers,Free private repositories !:)
Sign up
文件
This repository doesn't specify license. Please pay attention to the specific project description and its upstream code dependency when using it.
Clone or Download
POpenGLWidget.cpp 6.63 KB
Copy Edit Raw Blame History
StriveZhang authored 2023-03-13 10:37 . 添加新功能前准备
#include "POpenGLWidget.h"
#include <QTime>
#include "Position.h"
// 定义 缓冲区
//unsigned int VBO, VAO;
unsigned int VAOs[3], VBOs[3], EBO;
POpenGLWidget::POpenGLWidget(QWidget* parent) : QOpenGLWidget(parent)
{
}
/*析构函数*/
POpenGLWidget::~POpenGLWidget()
{
makeCurrent(); // 给一个当前状态
// 回收一个 buffer VBO
glDeleteBuffers(1, VBOs);
glDeleteVertexArrays(1, VAOs);
shaderProgram.release();
shaderProgram.removeAllShaders();
doneCurrent(); // 退出当前状态
}
/*实现一个对外的接口*/
void POpenGLWidget::drawShape(Shape shape)
{
// 实现一个对外的接口
m_shape = shape;
// 需要从 paintGL() 函数外面实现一个图形的重新绘制时 需要调用update()函数
update();
}
// 线框模式渲染
void POpenGLWidget::setWirefarme(bool wireframe)
{
makeCurrent();
if (wireframe) {
// 进行线框绘制
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
else {
// 实现填充绘制
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
update(); // 重绘 更新画板
doneCurrent();
}
// 填充颜色
void POpenGLWidget::fillColor(bool color)
{
makeCurrent();
if (color) {
/*4 通过shader渲染图形*/
bool success;
// 资源文件形式渲染图形
shaderProgram.addCacheableShaderFromSourceFile(QOpenGLShader::Vertex, ":/PaintApp/shapes.vert");
shaderProgram.addCacheableShaderFromSourceFile(QOpenGLShader::Fragment, ":/PaintApp/shapes.frag");
// 连接
success = shaderProgram.link();
if (!success)
{
qDebug() << "ShaderProgram is err!" << shaderProgram.log();
}
shaderProgram.bind();
}
else {
// 取消shader着色
shaderProgram.release();
shaderProgram.removeAllShaders();
// 实现填充绘制
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
update(); // 重绘 更新画板
doneCurrent();
}
// 自动变色
void POpenGLWidget::autoColor(bool autoColor)
{
makeCurrent();
if (autoColor) {
timer.start(100);
// connect(&timer, SIGNAL(timeout()), this, SLOT(on_timeout()));
// Lambda 方法实现
connect(&timer, &QTimer::timeout, this, [=]()
{
makeCurrent();
// 通过timer 拿到一个值
int timeValue = QTime::currentTime().second();
float greenValue = (sin(timeValue) / 2.0f) + 0.5f;
// 将值给到资源文件
shaderProgram.setUniformValue("outColor", 0.0f, greenValue, 0.0f, 1.0f);
doneCurrent();
update();
});
bool success;
shaderProgram.addCacheableShaderFromSourceFile(QOpenGLShader::Vertex, ":/PaintApp/shapes.vert");
shaderProgram.addCacheableShaderFromSourceFile(QOpenGLShader::Fragment, ":/PaintApp/outTIme.frag");
success = shaderProgram.link();
if (!success)
{
qDebug() << "ShaderProgram is err!" << shaderProgram.log();
}
shaderProgram.bind();
}
else {
// 取消shader着色
shaderProgram.release();
shaderProgram.removeAllShaders();
// 实现填充绘制
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
update();
doneCurrent();
}
// 渐变
void POpenGLWidget::gradualColor(bool gradual)
{
makeCurrent();
if (gradual) {
bool success;
shaderProgram.addCacheableShaderFromSourceFile(QOpenGLShader::Vertex, ":/PaintApp/differColor.vert");
shaderProgram.addCacheableShaderFromSourceFile(QOpenGLShader::Fragment, ":/PaintApp/differColor.frag");
success = shaderProgram.link();
if (!success)
{
qDebug() << "ShaderProgram is err!" << shaderProgram.log();
}
shaderProgram.bind();
}
else {
// 取消shader着色
shaderProgram.release();
shaderProgram.removeAllShaders();
// 实现填充绘制
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
update(); // 重绘 更新画板
doneCurrent();
}
// 纹理填充
void POpenGLWidget::textureFill(bool isTexture)
{
makeCurrent();
if (isTexture) {
bool success;
shaderProgram.addCacheableShaderFromSourceFile(QOpenGLShader::Vertex, ":/images/texture.vert");
shaderProgram.addCacheableShaderFromSourceFile(QOpenGLShader::Fragment, ":/images/texture.frag");
success = shaderProgram.link();
if (!success)
{
qDebug() << "ShaderProgram is err!" << shaderProgram.log();
}
// 进行纹理的载入 qimage 将其变为图片 由于 y 轴可能是反的,所以需要一个mirrored作为镜像
textureWall = new QOpenGLTexture(QImage(":/images/images/texture.webp").mirrored());
// 绑定纹理资源 通道为0
textureWall->bind(0);
shaderProgram.bind();
}
else {
// 取消shader着色
shaderProgram.release();
shaderProgram.removeAllShaders();
// 实现填充绘制
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
update(); // 重绘 更新画板
doneCurrent();
}
// initializeGL 设置OpenGL的资源和状态,第一次调用 resizeGL、paintGL 之前调用一次
void POpenGLWidget::initializeGL()
{
// 初始化
initializeOpenGLFunctions();
// 创建VAO VBO
glGenVertexArrays(3, VAOs);
glGenBuffers(3, VBOs);
// 绑定三角形坐标 到 0
glBindVertexArray(VAOs[0]);
glBindBuffer(GL_ARRAY_BUFFER, VBOs[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(colorTriangle), colorTriangle, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
// 纹理坐标的解析方式
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
// 绑定矩形坐标和索引到 2
glBindVertexArray(VAOs[2]);
glBindBuffer(GL_ARRAY_BUFFER, VBOs[2]);
// 绑定EBO
glGenBuffers(1, &EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(rectIndex), rectIndex, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, sizeof(colorRect), colorRect, GL_STATIC_DRAW);
// 显卡数据解析协议
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// 渐变颜色属性传入
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
// 纹理坐标的解析方式
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
// 使用完成 解绑VAO, VBO
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
// resizeGL 设置OpenGL视口、投影等 widget调整大小 或者首次显示的时候调用
void POpenGLWidget::resizeGL(int w, int h)
{
// 暂时不用这两个参数时
Q_UNUSED(w);
Q_UNUSED(h);
}
// paintGL 渲染OpenGL场景, widget需要更新时调用
void POpenGLWidget::paintGL()
{
// 画板背景颜色的改变
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
// 进行一个深度测试
glEnable(GL_DEPTH_TEST); // 打开了一个缓冲区
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/*实现多图形的绘制*/
switch (m_shape)
{
case POpenGLWidget::None:
break;
case POpenGLWidget::Triangle:
glBindVertexArray(VAOs[0]);
glDrawArrays(GL_TRIANGLES, 0, 3);
break;
case POpenGLWidget::Rect:
glBindVertexArray(VAOs[2]);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
break;
default:
break;
}
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化