Fetch the repository succeeded.
#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;
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。