【问题标题】:Draw GL_LINE in QOpenGLWidget using array of coordinates使用坐标数组在 QOpenGLWidget 中绘制 GL_LINE
【发布时间】:2021-01-31 22:05:34
【问题描述】:

我已经使用 QtCreator 完成了工作应用程序。我的渲染类是

GLRendWindow::GLRendWindow(QWidget *parent): QOpenGLWidget(parent)

现在我想使用具有顶点坐标的数组来绘制对象。
我在此页面上找到了一些绘制三角形的教程: OpenGL Window Example

我尝试重复使用它来绘制简单的线条

void GLRendWindow::drawLine()
{
    GLfloat line[] =
    {
        0.5f, 1.0f,
        0.5f, -1.0f
    };
    GLfloat line_colors[] =
    {
        1.0f, 0.0f, 0.0f, // red
        0.0f, 0.0f, 1.0f, // blue
    };
    shaderProgram->bind();
    glVertexAttribPointer(posAttr, 2, GL_FLOAT, GL_FALSE, 0, line);
    glVertexAttribPointer(colAttr, 3, GL_FLOAT, GL_FALSE, 0, line_colors);
    glEnableVertexAttribArray(colAttr);
    glEnableVertexAttribArray(posAttr);
    glDrawArrays(GL_LINE, 0, 2);
    glDisableVertexAttribArray(posAttr);
    glDisableVertexAttribArray(colAttr);
    shaderProgram->release();
}

也是我的初始化方法

void GLRendWindow::initializeGL()
{
    initializeOpenGLFunctions();
    glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
    glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB );

    shaderProgram = new QOpenGLShaderProgram(this);
    shaderProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
    shaderProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
    shaderProgram->link();
    posAttr = shaderProgram->attributeLocation("posAttr");
    colAttr = shaderProgram->attributeLocation("colAttr");
}

及绘图方法

void GLRendWindow::paintGL()
{
    glClear( GL_COLOR_BUFFER_BIT );
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
    drawLine();

    if (isUpdated)
    {
       //some other stuff

        isUpdated = false;
    }
    glFlush();
}

和调整大小的方法

void GLRendWindow::resizeGL(int w, int h)
{
    glViewport( 0, 0, w, h );
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();

    if ( w < h && w > 0 )
    {
        glFrustum( - 1.0, 1.0, - 1.0 * h / w, 1.0 * h / w, 1.0, 5.0 );
    }
    else
    {
        if ( w >= h && h > 0 )
        {
            glFrustum( - 0.3 * w / h, 0.3 * w / h, - 0.3, 0.3, 0.5, 5.0 );
        }
    }
}

但是当我运行应用程序时,没有绘制任何内容。没有错误,没有例外,什么都没有。 在本教程中,我看到了

static const char *vertexShaderSource =
    "attribute highp vec4 posAttr;\n"
    "attribute lowp vec4 colAttr;\n"
    "varying lowp vec4 col;\n"
    "uniform highp mat4 matrix;\n"
    "void main() {\n"
    "   col = colAttr;\n"
    "   gl_Position = matrix * posAttr;\n"
    "}\n";

static const char *fragmentShaderSource =
    "varying lowp vec4 col;\n"
    "void main() {\n"
    "   gl_FragColor = col;\n"
    "}\n";

可能解决方案隐藏在这里,但我完全不明白它是什么以及这里发生了什么。我什至不确定这是否是绘制简单线条所必需的。
我应该怎么做才能使用坐标数组看到直线?

【问题讨论】:

    标签: c++ qt opengl draw qopenglwidget


    【解决方案1】:

    问题也在这里

    glDrawArrays(GL_LINE, 0, 2);
    

    应该是

    glDrawArrays(GL_LINES, 0, 2);
    

    我不得不改变

    static const char *vertexShaderSource =
        "attribute highp vec4 posAttr;\n"
        "attribute lowp vec4 colAttr;\n"
        "varying lowp vec4 col;\n"
        "uniform highp mat4 matrix;\n"
        "void main() {\n"
        "   col = colAttr;\n"
        "   gl_Position = matrix * posAttr;\n"
        "}\n";
    

    static const char *vertexShaderSource =
        "attribute highp vec4 posAttr;\n"
        "attribute lowp vec4 colAttr;\n"
        "varying lowp vec4 col;\n"
        "void main() {\n"
        "   col = colAttr;\n"
        "   gl_Position = posAttr;\n"
        "}\n";
    

    【讨论】:

    • 解释在哪里?
    • @Rabbid76 我想你关于颜色的建议是对的。但是由于某种原因,当我写我的解决方案时,你的帖子不可见,我坚持你删除了它。 glDrawArray 只是简单的符号错误。我认为不需要任何解释。如果是“矩阵”,我只是将其删除。我想某些转换需要它,但在这种情况下不是必需的。
    • 重点是glMatrixMode( GL_MODELVIEW );glLoadIdentity();等在使用shader的时候是没用的。如果要设置变换矩阵,则必须设置矩阵统一。看我的回答。
    • @Rabbid76 你是对的。我的代码可能很乱,因为一开始我从基本功能开始,现在我只使用更“现代”的东西(如果它是正确的词)。此外,我迷失在所有这些可能性中。
    【解决方案2】:

    您错过了为颜色属性 (attribute lowp vec4 colAttr;) 指定通用顶点属性数据数组。这类似于指定顶点属性。
    例如,将以下代码添加到GLRendWindow::drawLine

    GLfloat line_colors[] =
    {
        1.0f, 0.0f, 0.0f, // red
        0.0f, 0.0f, 1.0f  // blue
    };
    glVertexAttribPointer(colAttr, 3, GL_FLOAT, GL_FALSE, 0, line_colors);
    glEnableVertexAttribArray(colAttr);
    

    你没有指定颜色属性数组,所以colAttr的值默认是(0,0,0)。实际上你在黑色背景上画了一条黑线。


    您正在混合使用不同的技术。你有一个带有矩阵Uniform的着色器程序:

    uniform highp mat4 matrix;\n"
    void main() {
       // [...]
    
       gl_Position = matrix * posAttr;
    }
    

    你根本没有设置这件制服。相反,您尝试设置传统的 OpenGL 固定函数矩阵。遗留当前矩阵的内容不会神奇地出现在单一变量中。

    使用setUniformValue设置矩阵uniform的值:

    QMatrix4x4 matrix;
    
    int matrix_location = shaderprogram->uniformLocation("matrix");
    
    matrix.setToIdentity();
    shaderprogram->setUniformValue(matrix_location, matrix);
    

    【讨论】:

    • 我已经在我的第一篇文章中根据您的提示更新了代码。不幸的是结果是一样的——什么都没有。我还添加了我的调整大小方法。
    • @rainbow 你有 2 个顶点,所以你也需要 2 个颜色属性。为什么要删除第二个颜色属性?
    • 你是对的。这是复制粘贴错误。即使有两种颜色也不起作用。我想知道也许我在视图之外画了这条线?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-08
    • 1970-01-01
    • 2021-05-17
    • 2015-10-17
    • 1970-01-01
    • 2023-01-17
    相关资源
    最近更新 更多