1

I have a program that renders FACET geometry and then plots data over top of the geometry in the same OpenGL context. Everything is working as intended when doing color by vertex from a VBO that defines facet triangles and their associated colors, however the user has requested the ability to set all of the geometry vertices to a single color (GUI toggle).

Is there any way to do this without going in and setting the color portions of the VBO to that color? Just seems very inefficient, but I can't get anything I've tried from hours of googling to work.

Using C++, QT6+

Fragment Shader

#version 150 core
#ifdef GL_ES
// Set default precision to medium
precision mediump int;
precision mediump float;
#endif

in vec3 Color;
out vec4 outColor;

void main()
{
    outColor = vec4(Color,1.0f);
}

Vertex Shader

#version 150 core
#ifdef GL_ES
// Set default precision to medium
precision mediump int;
precision mediump float;
#endif

uniform mat4 mvp_matrix;
attribute vec4 a_position;
attribute vec2 a_texcoord;
varying vec2 v_texcoord;
attribute vec3 color;
varying vec3 Color;

void main()
{
    Color = color;

    // Calculate vertex position in screen space
    gl_Position = mvp_matrix * a_position;

    // Pass texture coordinate to fragment shader
    // Value will be automatically interpolated to fragments inside polygon faces
    v_texcoord = a_texcoord;
}

Relevant snippets of code:

// initializing the buffers from vectors of structures
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // Geometry
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // Get a copy of the geometry to reference here
    std::vector<storedGeometry::facetData> tGeom = gUseGeom.getGeom();
    // Convert vector to array
    storedGeometry::facetData* aGeom = tGeom.data();

    // Transfer vertex data to VBO 0
    geomBuf.bind();
    geomBuf.allocate(aGeom, int(tGeom.size() * sizeof(storedGeometry::facetData)));

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // Currents
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // Get a copy of the currents data to reference here
    std::vector<storedGeometry::facetData> tCurrents = gUseCurrents.getGeom();
    // Convert vector to array
    storedGeometry::facetData* aCurrent = tCurrents.data();

    // Transfer vertex data to VBO 1
    currentsBuf.bind();
    currentsBuf.allocate(aCurrent, int(tCurrents.size() * sizeof(storedGeometry::facetData)));




// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// drawing 
// Get shader variable locations
    int vertexLocation = program->attributeLocation("a_position");
    int colorLocation = program->attributeLocation("color");
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // Plot Geometry
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    if (bGeomVisible) {
        geomBuf.bind();
        program->enableAttributeArray(vertexLocation);
        program->setAttributeBuffer(vertexLocation, GL_FLOAT, 0, 3, sizeof(QVector3D));

        program->enableAttributeArray(colorLocation);
        if (bCobbleSolid) { // Solid
// This is what I can't get to work ************************************
            //program->setAttributeValue(colorLocation, 1.0, 1.0, 1.0);
            program->setAttributeValue(colorLocation, QVector3D(1.0,1.0,1.0));
        } else { // Cobble
            program->setAttributeBuffer(colorLocation, GL_FLOAT, 3*sizeof(QVector3D), 3, sizeof(QVector3D));
        }

        // Set polygon/wiremesh or solid/filled mode based on fill/wire toggle
        if (bFillWire) {
            // Polygon = TRUE
            glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
        } else {
            // Filled = FALSE
            glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
        }
        // Draw geometry
        glDrawArrays(GL_TRIANGLES, 0, gUseGeom.gSize() * 6);
    }
    // Debugging
    //out << "gUseGeom.gSize(): " << gUseGeom.gSize() << Qt::endl;
    // Draw cube geometry
    //glDrawElements(GL_TRIANGLES, gUseGeom.gSize() * 3, GL_UNSIGNED_SHORT, 0);
    //glDrawArrays(GL_TRIANGLES, 0, gUseGeom.gSize() * 6);

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // Plot Currents
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    if (bCurrentsVisible) {
        currentsBuf.bind();
        program->enableAttributeArray(vertexLocation);
        program->setAttributeBuffer(vertexLocation, GL_FLOAT, 0,                   3, sizeof(QVector3D));
        program->enableAttributeArray(colorLocation);
        program->setAttributeBuffer(colorLocation,  GL_FLOAT, 3*sizeof(QVector3D), 3, sizeof(QVector3D));
        glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
        glDrawArrays(GL_TRIANGLES, 0, gUseCurrents.gSize() * 6);
    }
1
  • Just create a seperate program that has a uniform colour attribute instead of the varying colour. The colorLocation will return -1 if it isn't available, so test for that instead of enabling the colorLocation vertex attribute array. (obviously you'll need to set the uniform colour value, or simply hardcode it if you really must) Commented Nov 15, 2022 at 6:38

1 Answer 1

1

When a specific vertex attribute array is not enabled (with glEnableVertexAttribArray) then the value for that attribute, for all rendered vertices, is taken from the current vertex attribute value, as defined by the glVertexAttrib family of functions.

You forgot to disable the vertex attribute array, therefore the current vertex attribute value isn't used. You can fix it as follows:

    if (bCobbleSolid) { // Solid
        program->disableAttributeArray(colorLocation);
        program->setAttributeValue(colorLocation, QVector3D(1.0,1.0,1.0));
    } else { // Cobble
        program->enableAttributeArray(colorLocation);
        program->setAttributeBuffer(colorLocation, GL_FLOAT, 3*sizeof(QVector3D), 3, sizeof(QVector3D));
    }
Sign up to request clarification or add additional context in comments.

1 Comment

That instantly fixed the problem, thank you so much! And thank you for explaining why!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.