0

I'm drawing the following rectangle 100 times:

float vertices[] = {
         0.05f,   0.05, // top right
         0.05f,  -0.05f,  // bottom right
        -0.05f, -0.05f, // bottom left
        -0.05f,  0.05f   // top left 
};
unsigned int indices[] = {  // note that we start from 0!
        0, 1, 3,  // first Triangle
        1, 2, 3   // second Triangle
};

I'm passing to it a transformation matrix defined as follows

float translations[1600];
int index = 0;
float offset = 0.1f;
float width = 1.0f;
float height = 1.0f;
for (int y = -10; y < 10; y += 2)
{
        float cy = ((float)y)/10.0f + offset;
        for (int x = -10; x < 10; x += 2)
        {
            float angle = x * y;
            float cx = ((float)x)/10.0f + offset;
            float R[16] = 
                { width * cos(angle), width * sin(angle), 0, 0, // first column
                    height * -sin(angle), height * cos(angle), 0, 0,
                    0, 0, 1.0f, 0,
                    cx, cy, 0, 1.0f}; // translation column

            for (int i=0; i<16;i++) {
                translations[index+i] = R[i];
            }

            index += 16;
        }
}

However, when calling

glDrawElementsInstanced(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0, 100);

I only get 25 rectangles. I can only get 100 if pass 400 as the amount to draw. Here is how I'm setting up the vertex attrib pointers:

glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 4*sizeof(float), (void*)0);
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 4*sizeof(float), (void*)(4*sizeof(float)));
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, 4*sizeof(float), (void*)(2*4*sizeof(float)));
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, 4*sizeof(float), (void*)(3*4*sizeof(float)));

glVertexAttribDivisor(1, 1);
glVertexAttribDivisor(2, 1);
glVertexAttribDivisor(3, 1);
glVertexAttribDivisor(4, 1);

Here is the full code


    // store instance data in an array buffer
    // --------------------------------------
    float translations[1600];
    int index = 0;
    float offset = 0.1f;
    float width = 1.0f;
    float height = 1.0f;
    for (int y = -10; y < 10; y += 2)
    {
        float cy = ((float)y)/10.0f + offset;
        for (int x = -10; x < 10; x += 2)
        {
            float angle = x * y;
            float cx = ((float)x)/10.0f + offset;
            float R[16] = 
                { width * cos(angle), width * sin(angle), 0, 0, // first column
                    height * -sin(angle), height * cos(angle), 0, 0,
                    0, 0, 1.0f, 0,
                    cx, cy, 0, 1.0f}; // translation column

            for (int i=0; i<16;i++) {
                translations[index+i] = R[i];
            }

            index += 16;
        }
    }

    unsigned int instanceVBO;
    glGenBuffers(1, &instanceVBO);
    glBindBuffer(GL_ARRAY_BUFFER, instanceVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(translations), translations, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    float vertices[] = {
         0.05f,   0.05, // top right
         0.05f,  -0.05f,  // bottom right
        -0.05f, -0.05f, // bottom left
        -0.05f,  0.05f   // top left 
    };
    unsigned int indices[] = {  // note that we start from 0!
        0, 1, 3,  // first Triangle
        1, 2, 3   // second Triangle
    };
    
    unsigned int VAO, VBO, EBO;

    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glGenBuffers(1, &EBO);
    // bind the Vertex Array Object first, then bind and set vertex buffer(s), 
    // and then configure vertex attributes(s).
    glBindVertexArray(VAO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);

    glEnableVertexAttribArray(0);
    // also set instance data
    glBindBuffer(GL_ARRAY_BUFFER, instanceVBO); // this attribute comes from a different vertex buffer
    //glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
    //glBindBuffer(GL_ARRAY_BUFFER, 0);
    //glVertexAttribDivisor(1, 1); // tell OpenGL this is an instanced vertex attribute.
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 4*sizeof(float), (void*)0);
    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 4*sizeof(float), (void*)(4*sizeof(float)));
    glEnableVertexAttribArray(3);
    glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, 4*sizeof(float), (void*)(2*4*sizeof(float)));
    glEnableVertexAttribArray(4);
    glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, 4*sizeof(float), (void*)(3*4*sizeof(float)));

    glVertexAttribDivisor(1, 1);
    glVertexAttribDivisor(2, 1);
    glVertexAttribDivisor(3, 1);
    glVertexAttribDivisor(4, 1);

    glBindVertexArray(0);
    while (!glfwWindowShouldClose(window)) 
    {
        // input
        // -----
        process_input(window);

        // render
        // ------
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        glUseProgram(shaderProgram);

        glBindVertexArray(VAO);
        glDrawElementsInstanced(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0, 100);
        glBindVertexArray(0);
         
       // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
       // -------------------------------------------------------------------------------
       glfwSwapBuffers(window);
       glfwPollEvents();

    }

Shader

#version 330 core
layout (location = 0) in vec2 aPos;
layout (location = 1) in mat4 transform;

out vec2 TexCoord;

void main()
{
    gl_Position = transform * vec4(aPos, 0, 1.0);
}

I did find this question but the answer uses GL 4.2 and I'm not sure if the questions are the same. To write this code I followed learnopengl's instancing chapter.

Samuel
  • 378
  • 1
  • 9

1 Answers1

0

I've found the problem, in glVertexAttribPointer I should use 16*sizeof(float) for the stride instead of 4*sizeof(float)

Samuel
  • 378
  • 1
  • 9