简体   繁体   English

如何使用 qopenglwidget 中的线将缓冲区中的一些顶点渲染为点而其余顶点渲染?

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

I have a set of vertices and normals stored in a buffer.我在缓冲区中存储了一组顶点和法线。 I want to display most of the vertices as points but i want draw lines for the remaining few vertices.我想将大多数顶点显示为点,但我想为剩余的几个顶点画线。 These are all stored inside one vector with the points part in the front and i know the location of the buffer until they are to be displayed using points.这些都存储在一个向量中,点部分在前面,我知道缓冲区的位置,直到使用点显示它们。 I also know the count of elements for each drawing task.我也知道每个绘图任务的元素数量。 I am using only one vao and one buffer object for this task.我只使用一个 vao 和一个缓冲区对象来完成这项任务。

I initialize the GLWidget with the following code:我使用以下代码初始化 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();
}

Where the functions setupBuffer() setupVertexAtrribs() do the same tasks as their names imply.函数 setupBuffer() setupVertexAtrribs() 执行其名称所暗示的相同任务。 The vertices are layed out in the buffer with xyz positions of the vertex followed by the xyz of its associated normal.顶点在缓冲区中布局,顶点的 xyz 位置后跟其关联法线的 xyz。 They are implemented as follows它们的实现方式如下

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();
}

Now, the QVector vertices is the buffer that is being passed to opengl.现在,QVector 顶点是传递给 opengl 的缓冲区。 The last few entries in this vector are the vertices that need to be drawn using GL_LINES.这个向量中的最后几个条目是需要使用 GL_LINES 绘制的顶点。

My paintGL() function looks something like this:我的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 is another vector that contains points that need to be drawn using lines. QVector camVertices 是另一个包含需要使用线绘制的点的向量。 The data in camVertices is appended to the end of the vector 'Vertices' before rendering. camVertices 中的数据在渲染之前附加到向量“Vertices”的末尾。 As seen in the above code, I call glDrawArrays function twice - first, starting from 0 index of the buffer, second, starting from where the previous call ended to display the remaining of the points.从上面的代码中可以看出,我调用了 glDrawArrays 函数两次——第一次,从缓冲区的 0 索引开始,第二次,从前一次调用结束的地方开始,以显示剩余的点。

The problem is that the points are being displayed fine.问题是这些点显示得很好。 However the second call only displays the points but does not draw any lines.然而,第二次调用只显示点但不绘制任何线。

Here's a link to a screenshot of the displayed output - https://drive.google.com/open?id=1i7CjO1qkBALw78KKYGvBteydhfAWh3wh这是显示输出屏幕截图的链接 - https://drive.google.com/open?id=1i7CjO1qkBALw78KKYGvBteydhfAWh3wh

The picture shows an example of the displayed out where the bright green points seen on the top outlying from the rest (box of many points) are the ones that are to be drawn with lines.图片显示了一个显示出来的例子,在顶部看到的亮绿色点与其余部分(许多点的框)是要用线绘制的点。 However, I only see points but not any lines.但是,我只看到点而不是任何线。

i did a simple test and i'm able to draw points and lines using the following code:我做了一个简单的测试,我能够使用以下代码绘制点和线:

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

Which is not very different from yours except for the variables.除了变量之外,这与您的没有太大不同。 I'm also using 1 VAO.我也在使用 1 个 VAO。 So it's definitely possible to draw lines after points as we would expect.所以绝对有可能像我们期望的那样在点之后画线。

Could you try the same (using an integer instead of your variables)你能试试吗(使用整数而不是变量)

Can you show the debug information on your vertices?你能在你的顶点上显示调试信息吗?

Can you upload a minimal compilable example?你能上传一个最小的可编译示例吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM