使用坐标数组在QOpenGLWidget中绘制GL_LINE

问题描述

我有使用QtCreator完成的应用程序。我的渲染类是

    Form {
        ForEach(nameArray,id: \.self) { name in
            Button(action: {
                selectedname = name
                showLink = true
            }) {
                Text(name)
            }
        }
    }
    .background(Group{
        if showLink {
            NavigationLink(destination: NameView(selectedname: selectedname),isActive: $linkIsActive) {
                EmptyView()
            }
        }
    })

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

我试图重用它来绘制简单的线条

glrendWindow::glrendWindow(QWidget *parent): qopenglwidget(parent)

也是我的初始化方法

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

和绘制方法

void glrendWindow::initializeGL()
{
    initializeOpenGLFunctions();
    glClearColor( 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,w,h );
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();

    if ( w < h && w > 0 )
    {
        glFrustum( - 1.0,1.0,- 1.0 * h / w,1.0 * h / w,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 );
        }
    }
}

可能将解决方案隐藏在这里,但是我完全不明白它的用途以及正在发生什么。我什至不确定画简单线条是否必要。
如何使用坐标数组查看直线?

解决方法

问题也在这里

glDrawArrays(GL_LINE,2);

应该是

glDrawArrays(GL_LINES,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";
,

您未设置为color属性(attribute lowp vec4 colAttr;)指定通用顶点属性数据的数组。这类似于指定顶点属性。
例如,将以下代码添加到GLRendWindow::drawLine

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

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


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

uniform highp mat4 matrix;\n"
void main() {
   // [...]

   gl_Position = matrix * posAttr;
}

您完全不需要设置这种制服。相反,您尝试设置旧版OpenGL固定功能矩阵。旧式当前矩阵的内容不会神奇地出现在the变量中。

使用setUniformValue来设置矩阵均一的值:

QMatrix4x4 matrix;
int matrix_location = shaderprogram->uniformLocation("matrix");

matrix.setToIdentity();
shaderprogram->setUniformValue(matrix_location,matrix);