C++ - Qt Framework - Using 1 OpenGL VAO and 2 VBOs with only 1 array for both position and color of each vertex

As we saw, in the last tutorial about using a VAO and VBO to handle 2 different objects on the scene with OpenGL, it's possible to have 2 arrays of vertex: one to manage the position and one to deal with the color.

This time we are going to see how to handle it with only one array.

So let's get started.

First of all

It's  an easy example with only 3 points on the screen and each one with one different color: red, green and blue (the famous RGB).

The code is essentially the same as the previous tutorial so we'll focus only on the difference, that is how to deal with only one array for both position and color of each vertex.

All happens in the initialize() method of the badprogDisplay.cpp file.

We have indeed an array of QVector3D named arrayVertex.

This array is made of 6 QVector3D and each one made of 3 floats.

The type float is really important there because it's what we are going to pass as argument in the setAttributeBuffer() method.

This method has 5 parameters:

  1. The location
  2. The type (of each element in the array)
  3. The offset
  4. The tuple size
  5. The stride

The location is the variable linked with our shader.

The type is float in our example.

The offset describes at which position we are supposed to start reading our value.

The tuple size is the number of elements to read to get a vertex (3 elements to get a vertex position and 3 to get a vertex color).

The stride is the number of elements that composes a "line" in the array.

By line I mean the number of elements for a position and its color, so in our case it's 6 (3 elements * 2).

Here we are, it's time to code a bit.

Code

The code is exactly the same as the last tutorial, only the badprogDisplay.cpp file is different.

So just replace the following code.

badprogDisplay.cpp

#include "badprogDisplay.h"

#include <QtGui/QOpenGLShaderProgram>

// BadproG.com

// ============================================================================
//
// ============================================================================
BadprogDisplay::BadprogDisplay()
    : _program(nullptr)
    , _frame(0)
{
    //
    setTitle("Badprog - 1 VAO and 2 VBO with only 1 array for Position and Color");
}

// ============================================================================
//
// ============================================================================
void BadprogDisplay::initialize() {
    // Program.
    _program = new QOpenGLShaderProgram(this);
    _program->addShaderFromSourceFile(QOpenGLShader::Vertex, ":vertex");
    _program->addShaderFromSourceFile(QOpenGLShader::Fragment, ":fragment");

    // Linking.
    _program->link();

    // Attributes.
    _attribute1_position         = _program->attributeLocation("layoutPosition");
    _attribute1_color            = _program->attributeLocation("layoutColor");

    // Uniforms.
    _uniformForShader1_matrix    = _program->uniformLocation("shaderMatrix");

    // Enabling the point size modification.
    glEnable(GL_PROGRAM_POINT_SIZE);

    // Array of vertex
    QVector3D arrayVertex[] = {
        // First triangle            // Color
        QVector3D(0.0f0.0f0.0f), QVector3D(1.0f0.0f0.0f),   // Red
        QVector3D(0.5f, 1.0f0.0f), QVector3D(0.0f1.0f0.0f),   // Green
        QVector3D(1.0f1.0f0.0f), QVector3D(0.0f0.0f1.0f),   // Blue
    };

    // ------------------------------------------
    // VAO 1
    // ------------------------------------------
    _vao1.create();
    _vao1.bind();

    // VBO 1
    int bpOffset  = 0;
    int bpTuple   = 3;
    int bpStride  = 6 * sizeof (GL_FLOAT);

    // Buffer 1
    _vbo1_position.create();
    _vbo1_position.bind();
    _vbo1_position.allocate(arrayVertexsizeof (GL_FLOAT) * 18);

    // program
    _program->enableAttributeArray(_attribute1_position);
    _program->setAttributeBuffer(
                _attribute1_position,
                GL_FLOAT,
                bpOffset,
                bpTuple,
                bpStride
                );

    //
    bpOffset = 3 * sizeof (GL_FLOAT);

    // Buffer 2
    _vbo1_color.create();
    _vbo1_color.bind();
    _vbo1_color.allocate(arrayVertexsizeof (GL_FLOAT) * 18);

    // program
    _program->enableAttributeArray(_attribute1_color);
    _program->setAttributeBuffer(
                _attribute1_color,
                GL_FLOAT,
                bpOffset,
                bpTuple,
                bpStride
                );
}

// ============================================================================
//
// ============================================================================
void BadprogDisplay::render() {
    // Viewport
    glViewport(00width(), height());

    // Clear whole buffer
    glClear(GL_COLOR_BUFFER_BIT);

    //
    _program->bind();
    _vao1.bind();

    //
    QMatrix4x4 matrixFromCpp1;
    matrixFromCpp1.perspective(70.0f1.0f0.1f100.0f);
    matrixFromCpp1.translate(0.0f0.0f, -2.0f);

    //
    _program->setUniformValue(_uniformForShader1_matrixmatrixFromCpp1);

    //
    glDrawArrays(GL_POINTS, 03);

    //
    _vao1.release();

    //
    _program->release();

    //
    ++_frame;
}

Conclusion

If everything works fine you should see 3 points on the screen.

Now we have an interesting example to deal with many elements in only one array.

Good job you did it. heart

Add new comment

Plain text

  • No HTML tags allowed.
  • Lines and paragraphs break automatically.