QOpenGLWidget,QOpenGLWindow的问题

Posted

技术标签:

【中文标题】QOpenGLWidget,QOpenGLWindow的问题【英文标题】:problem with QOpenGLWidget, QOpenGLWindow 【发布时间】:2020-07-12 14:31:19 【问题描述】:

谁能告诉我为什么我的paintGL中的以下代码在使用DrawArrays函数时不绘制?我在最后一个 Windows 10 上的 Qt Creator 中使用 Qt 5.14.2。

几厘米;

我正在尝试使用以下声明来了解 Qt 中 OpenGL 实现之间的差异。随着时间的推移,我会使用我最喜欢的实现来编写我的应用程序。

    OpenGLWindow 类:公共 QWindow、公共 QOpenGLFunctions

当我将以下代码放在 render() 函数中时,效果很好,完全没有问题,非常好!!

    类 myOpenGLWidget:公共 QOpenGLWidget、公共 QOpenGLFunctions

我将代码放在paintGL 函数中。我可以为背景着色,但 glDrawArrays() 什么也不做。但是,我可以画一个三角形,glBegin 和 glEnd 语句之间的代码是成功的。我没有收到任何错误。我测试 m_program->bind() 调用的结果,结果返回 true。

    类 myQOpenGLWindow:公共 QOpenGLWindow,受保护的 QOpenGLFunctions

除了我将代码放在 render() 函数中之外,与 #2 相同。我可以为背景着色,但 glDrawArrays() 什么也不做。但是,我可以画一个三角形,glBegin 和 glEnd 语句之间的代码是成功的。我测试了 m_program->bind() 调用的结果,结果返回 true。

如果有人需要问,我是在阅读了几十个不同的教程之后这样做的,这是我能找到的最好的信息。

谢谢!!

// 绘制场景:

QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();

const qreal retinaScale = devicePixelRatio();

f->glViewport(0, 0, width() * retinaScale, height() * retinaScale);

f->glClearColor(red, green, blue, 1.0f);
f->glClear(GL_COLOR_BUFFER_BIT);

QMatrix4x4 matrix;
matrix.perspective(60.0f, 4.0f / 3.0f, 0.1f, 100.0f);
matrix.translate(0, 0, 0);
matrix.rotate(0, 1, 0, 0);

m_program->setUniformValue(m_matrixUniform, matrix);

glBegin(GL_TRIANGLES);
    glColor3f(1.0, 0.0, 0.0);
    glVertex3f(-0.5, -0.5, 0);
    glColor3f(0.0, 1.0, 0.0);
    glVertex3f( 0.5, -0.5, 0);
    glColor3f(0.0, 0.0, 1.0);
    glVertex3f( 0.0,  0.5, 0);
glEnd();

//f->glBindTexture(GL_TEXTURE_2D, 0);

bound = m_program->bind();

GLfloat line_vertices[2160];

for (int v=0;v<360;v++)
    
    line_vertices[(6*v)]=-3.5+float(v)/25;
    line_vertices[(6*v)+1]=1.1+qSin(5*2*v*(M_PI)/180);
    line_vertices[(6*v)+2]=-5;
    line_vertices[(6*v)+3]=-3.5+float(v+1)/25;
    line_vertices[(6*v)+4]=1.1+qSin(5*2*(v+1)*(M_PI)/180);;
    line_vertices[(6*v)+5]=-5;
    

GLfloat line_colors[2160];

for (int v=0;v<360;v++)
    
    line_colors[(6*v)]=1.0;
    line_colors[(6*v)+1]=0;
    line_colors[(6*v)+2]=0;
    line_colors[(6*v)+3]=1.0;
    line_colors[(6*v)+4]=0;
    line_colors[(6*v)+5]=0;
    

f->glVertexAttribPointer(m_posAttr, 3, GL_FLOAT, GL_FALSE, 0, line_vertices);
f->glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, 0, line_colors);

f->glEnableVertexAttribArray(m_posAttr);
f->glEnableVertexAttribArray(m_colAttr);

f->glDrawArrays(GL_LINES, 0, 360);

f->glDisableVertexAttribArray(m_colAttr);
f->glDisableVertexAttribArray(m_posAttr);

m_program->release();

【问题讨论】:

请说明您如何设置 VBO 和(如果使用 3.3 或更高版本)VAO。除此之外,您对glVertexAttribPointer 的使用看起来不正确——最后两个参数应该是当前绑定到GL_ARRAY_BUFFER 的缓冲区的步幅和偏移量(如果有记忆的话)。 当然可以。当我这样做时,您能想到为什么它在第一种情况下有效,而在其他两种情况下无效吗? GL_VERSION = 4.6.0 【参考方案1】:

GL_VERSION = 4.6.0

这是我定义位置和颜色顶点、VBO、位置和颜色缓冲区的各种设置以及 glDrawArrays 函数的代码部分。我已经在 render() 和 paintgl() 函数中尝试过这段代码。我没有得到任何错误,但我也没有得到漂亮的线条。但是在 begin() 和 end() 之间定义的三角形顶点确实会显示出来。

GLfloat line_vertices[2160];

for (int v=0;v<360;v++)
    
    line_vertices[(6*v)]=-3.5+float(v)/25;
    line_vertices[(6*v)+1]=1.1+qSin(5*2*v*(M_PI)/180);
    line_vertices[(6*v)+2]=-5;
    line_vertices[(6*v)+3]=-3.5+float(v+1)/25;
    line_vertices[(6*v)+4]=1.1+qSin(5*2*(v+1)*(M_PI)/180);;
    line_vertices[(6*v)+5]=-5;
    

GLfloat line_colors[2160];

for (int v=0;v<360;v++)
    
    line_colors[(6*v)]=1.0;
    line_colors[(6*v)+1]=0;
    line_colors[(6*v)+2]=0;
    line_colors[(6*v)+3]=1.0;
    line_colors[(6*v)+4]=0;
    line_colors[(6*v)+5]=0;
    

QOpenGLBuffer m_vertexBufferCube;
QOpenGLBuffer m_colorBufferCube;

m_program->setUniformValue(m_matrixUniform, matrix);

m_vertexBufferCube.create();
m_vertexBufferCube.setUsagePattern(QOpenGLBuffer::StaticDraw);
m_vertexBufferCube.allocate(line_vertices, 3 * 360 * sizeof(float));

m_colorBufferCube.create();
m_colorBufferCube.setUsagePattern(QOpenGLBuffer::StaticDraw);
m_colorBufferCube.allocate(line_colors, 3 * 360 * sizeof(float));

bound = m_vertexBufferCube.bind();
//m_program->setAttributeBuffer("vertexPosition", GL_FLOAT,0,3);
m_program->setAttributeBuffer(m_posAttr, GL_FLOAT,0,3);

m_colorBufferCube.bind();
//m_program->setAttributeBuffer("colorPosition", GL_FLOAT,0,3);
m_program->setAttributeBuffer(m_colAttr, GL_FLOAT,0,3);

//glVertexAttribPointer(m_posAttr, 3, GL_FLOAT, GL_FALSE, 0, line_vertices);
//glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, 0, line_colors);

//glEnableVertexAttribArray(m_posAttr);
//glEnableVertexAttribArray(m_colAttr);

glDrawArrays(GL_LINES, 0, 360);

【讨论】:

【参考方案2】:

当您要求查看我如何设置 VAO 时,我相信这就是您正在寻找的内容,如果我错了,请纠正我。

// Create Shader (Do not release until VAO is created)
m_program = new QOpenGLShaderProgram(this);
m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, ogl_vertexShaderSource);
m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, ogl_fragmentShaderSource);
m_program->link();
m_posAttr = m_program->attributeLocation("posAttr");
m_colAttr = m_program->attributeLocation("colAttr");
m_matrixUniform = m_program->attributeLocation("matrix");

m_program->release();

【讨论】:

我很快了解到,我对如何在 QT 中实现 VAO 或 VBO 的理解水平处于我认为我什至不会问一个好问题的水平。不过,较早的回复为我指明了正确的方向,我需要研究 VAO、VBO 以及它们如何与 QT 中的管道交互。我将对此进行更多研究,当我弄清楚时,我会发布我的答案。感谢大家的帮助。

以上是关于QOpenGLWidget,QOpenGLWindow的问题的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 QOpenGLWidget 渲染文本

没有子类化的 QOpenGLWidget

无法使用 QOpenGLWidget 读取 GL_DEPTH_COMPONENT

使用 QOpenGLWidget 优于普通 QWidget 的好处

无法在 QopenGLWidget 中捕获 QkeyEvent

在qt的QOpenGLWidget开启opengl的抗锯齿