簡體   English   中英

如何使用 qopenglwidget 中的線將緩沖區中的一些頂點渲染為點而其余頂點渲染?

[英]How to render some vertices in a buffer as points and the rest using lines in qopenglwidget?

我在緩沖區中存儲了一組頂點和法線。 我想將大多數頂點顯示為點,但我想為剩余的幾個頂點畫線。 這些都存儲在一個向量中,點部分在前面,我知道緩沖區的位置,直到使用點顯示它們。 我也知道每個繪圖任務的元素數量。 我只使用一個 vao 和一個緩沖區對象來完成這項任務。

我使用以下代碼初始化 GLWidget:

void GLWidget::initializeGL()
{
    connect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &GLWidget::cleanup);

    initializeOpenGLFunctions();
    glClearColor(0, 0, 0, m_transparent ? 0 : 1);

    m_program = new QOpenGLShaderProgram;
    m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, m_core ? vertexShaderSourceCore : vertexShaderSource);
    m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, m_core ? fragmentShaderSourceCore : fragmentShaderSource);
    m_program->bindAttributeLocation("vertex", 0);
    m_program->bindAttributeLocation("normal", 1);
    m_program->link();

    m_program->bind();
    m_projMatrixLoc = m_program->uniformLocation("projMatrix");
    m_mvMatrixLoc = m_program->uniformLocation("mvMatrix");
    m_normalMatrixLoc = m_program->uniformLocation("normalMatrix");
    m_lightPosLoc = m_program->uniformLocation("lightPos");
    m_vao.create();
    QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao);
    m_obj.create();
    setupBuffer();
    setupVertexAttribs();
    m_camera.setToIdentity();

    QVector3D camPos = QVector3D(0.0, 0.0, 15.0);
    m_camera.translate(-camPos);

    QVector3D camTarget = QVector3D(0.0, 0.0, 0.0);
    QVector3D camDirection = QVector3D(camPos - camTarget).normalized();
    QVector3D worldUp = QVector3D(0.0, 1.0, 0.0);
    QVector3D camRight = QVector3D::crossProduct(worldUp, camDirection).normalized();
    QVector3D camUp = QVector3D::crossProduct(camDirection, camRight);

    m_camera.lookAt(camPos, camTarget, camUp);
    // Light position is fixed.
    m_program->setUniformValue(m_lightPosLoc, QVector3D(0, 0, 200));

    m_program->release();
}

函數 setupBuffer() setupVertexAtrribs() 執行其名稱所暗示的相同任務。 頂點在緩沖區中布局,頂點的 xyz 位置后跟其關聯法線的 xyz。 它們的實現方式如下

void GLWidget::setupBuffer()
{
    m_obj.bind();
    m_obj.allocate(vertices.constData(), vertices.size() * sizeof(GLfloat));
}

void GLWidget::setupVertexAttribs()
{
    m_obj.bind();
    QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
    f->glEnableVertexAttribArray(0);
    f->glEnableVertexAttribArray(1);
    f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), reinterpret_cast<void *>(0));
    f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), reinterpret_cast<void *>(3 * sizeof(GLfloat)));
    m_obj.release();
}

現在,QVector 頂點是傳遞給 opengl 的緩沖區。 這個向量中的最后幾個條目是需要使用 GL_LINES 繪制的頂點。

我的paintGL() 函數看起來像這樣:

void GLWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glEnable(GL_POINT_SIZE);
    glEnable(GL_LINE_WIDTH);
    glPointSize(2);
    glLineWidth(10);

    m_world.setToIdentity();
    m_world.rotate(180.0f - (m_xRot / 16.0f), 1, 0, 0);
    m_world.rotate(m_yRot / 16.0f, 0, 1, 0);
    m_world.rotate(m_zRot / 16.0f, 0, 0, 1);
    m_world.scale(m_dispScale);

    QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao);
    m_program->bind();
    m_program->setUniformValue(m_projMatrixLoc, m_proj);
    m_program->setUniformValue(m_mvMatrixLoc, m_camera * m_world);
    QMatrix3x3 normalMatrix = m_world.normalMatrix();
    m_program->setUniformValue(m_normalMatrixLoc, normalMatrix);

    glDrawArrays(GL_POINTS, 0, vertices.size() - camVertices.size());
    // Draw camera frustums
    glDrawArrays(GL_LINES, vertices.size() - camVertices.size(), camVertices.size());
    //glDrawElements(GL_POINTS, vecIndices.size(), GL_UNSIGNED_INT, 0);

    m_program->release();
}

QVector camVertices 是另一個包含需要使用線繪制的點的向量。 camVertices 中的數據在渲染之前附加到向量“Vertices”的末尾。 從上面的代碼中可以看出,我調用了 glDrawArrays 函數兩次——第一次,從緩沖區的 0 索引開始,第二次,從前一次調用結束的地方開始,以顯示剩余的點。

問題是這些點顯示得很好。 然而,第二次調用只顯示點但不繪制任何線。

這是顯示輸出屏幕截圖的鏈接 - https://drive.google.com/open?id=1i7CjO1qkBALw78KKYGvBteydhfAWh3wh

圖片顯示了一個顯示出來的例子,在頂部看到的亮綠色點與其余部分(許多點的框)是要用線繪制的點。 但是,我只看到點而不是任何線。

我做了一個簡單的測試,我能夠使用以下代碼繪制點和線:

 glDrawArrays(GL_POINTS, 0, verticesCount() - 10); glDrawArrays(GL_LINES, 10, 10);

除了變量之外,這與您的沒有太大不同。 我也在使用 1 個 VAO。 所以絕對有可能像我們期望的那樣在點之后畫線。

你能試試嗎(使用整數而不是變量)

你能在你的頂點上顯示調試信息嗎?

你能上傳一個最小的可編譯示例嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM