<p>A problem I see in your code is that you take the <code>sizeof()</code> an unsized array, which yields the size of the <em>pointer</em> to that array and not the size of array itself.</p>
<pre><code>void CglSolidModel::loadModels(glm::vec3 vertices[], unsigned int indices[]) {
{
    ...
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    ...
}
</code></pre>
<p>Here is a small test case that demonstrates the issue.</p>
<pre><code>void func(int array[]) {
    printf(&quot;sizeof(array) = %d\n&quot;, sizeof(array));
}

int myArray[10];
func(myArray);
</code></pre>
<p>Output when compiled for x64:</p>
<pre><code>sizeof(array) = 8  
</code></pre>
<p>This is the size of the 64bit pointer to the array. You would expect 10*sizeof(int) = 40. In your code (assuming x64) it only sends 8 bytes of the vertice array to the VBO, which is enough to fill the XY coordinates for the first vertex. That goes some way to explaining why you only see 1 partial triangle.</p>
<p>It's not possible for C++ to determine the size of an unsized array. In C++ <code>int array[];</code> is equivalent to <code>const int *array;</code> and so <code>sizeof(array)</code> is the same in both cases. This isn't the case for sized arrays, <code>int array[10];</code> would give you 40 bytes as you would expect.</p>
<p>I would recommend you pass another parameter which contains the size of the array or use a container like <code>std::vector</code> which stores the size along with the array. Be aware that <code>std::vector</code> returns the number of elements and not the number of bytes which <code>glBufferData</code> expects.</p>

CC BY-SA 4.0
2021-03-12T20:18:18.023Z
Oh I understand, thanks so much, I'm gonna use sizeof(vertices[0])*vertexCount in this case.
Yair Camborda Morocho
CC BY-SA 4.0
2021-03-13T05:45:05.930Z
Happy to help. One small thing I noticed in your code was glBindVertexArray(1) after your VAO/VBO is loaded - What is object #1? Usually glBindVertexArray(0) is used to unbind VAO to openGL. Infact the call glBindBuffer(GL_ARRAY_BUFFER, 0); looks risky as you still have your VAO bound, I would suggest a call to glBindVertexArray(0) is all that is needed after initialisation, this will leave your VAO in its setup state
PaulHK
CC BY-SA 4.0
2021-03-12T07:01:05.773Z
2021-03-12T10:04:53.037Z
2021-03-12T10:04:53.037Z
PaulHK
<p>I'm trying to learn OpenGL in c++ (I used it in Java) but I have a problem, I make a triangle, but it doesn't draw on GL_FILL and in GL_LINE it just draw a line, I can't find my mistake, I guess my bug is in vertex buffers, but I can't detect it, can anyone help me please?</p>
<p>CglApp.cpp:</p>
<pre><code>    CglApp::CglApp() {

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

    glm::vec3 vertices2[] = {
            //{0.5f,  0.5f, 0.0f} ,  // top right
            {0.5f, -0.5f, 0.0f},  // bottom right
            {-0.5f, -0.5f, 0.0f},  // bottom left
            {-0.5f,  0.5f, 0.0f}   // top left
    };

    unsigned int indices2[] = {  // note that we start from 0!
            //0, 1, 3,  // first Triangle
            1, 2, 3   // second Triangle
    };


    cglSolidModel.loadModels(vertices,indices);
    cglSolidModel1.loadModels(vertices2,indices2);

}

CglApp::~CglApp() {

}

void CglApp::run() {

    while (!cglWindow.shouldClose()){

        // input
        // -----
        inputManager.processInput(cglWindow.getWindow());

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

        cglSolidModel.bind(cglShaders.getDefaultShader());
        cglSolidModel1.bind(cglShaders.getDefaultShader());

        // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
        // -------------------------------------------------------------------------------
        glfwSwapBuffers(cglWindow.getWindow());
        glfwPollEvents();

    }

}
</code></pre>
<p>CglShaders.cpp</p>
<pre><code>CglShaders::CglShaders() {
    createDefaultShader();
}

CglShaders::~CglShaders() {

}

void CglShaders::createDefaultShader() {

    const char *vertexShaderSource = &quot;#version 330 core\n&quot;
                                     &quot;layout (location = 0) in vec3 aPos;\n&quot;
                                     &quot;void main()\n&quot;
                                     &quot;{\n&quot;
                                     &quot;   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n&quot;
                                     &quot;}\0&quot;;
    const char *fragmentShaderSource = &quot;#version 330 core\n&quot;
                                       &quot;out vec4 FragColor;\n&quot;
                                       &quot;void main()\n&quot;
                                       &quot;{\n&quot;
                                       &quot;   FragColor = vec4(1.0f, 0.9f, 0.2f, 1.0f);\n&quot;
                                       &quot;}\n\0&quot;;

    createShader(vertexShaderSource,fragmentShaderSource);

}

void CglShaders::createShader(const char *vertexShaderSource, const char *fragmentShaderSource) {

    // build and compile our shader program
    // ------------------------------------
    // vertex shader
    unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &amp;vertexShaderSource, NULL);
    glCompileShader(vertexShader);
    // check for shader compile errors
    int success;
    char infoLog[512];
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &amp;success);
    if (!success)
    {
        glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
        std::cout &lt;&lt; &quot;ERROR::SHADER::VERTEX::COMPILATION_FAILED\n&quot; &lt;&lt; infoLog &lt;&lt; std::endl;
    }
    // fragment shader
    unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &amp;fragmentShaderSource, NULL);
    glCompileShader(fragmentShader);
    // check for shader compile errors
    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &amp;success);
    if (!success)
    {
        glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
        std::cout &lt;&lt; &quot;ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n&quot; &lt;&lt; infoLog &lt;&lt; std::endl;
    }
    // link shaders
    unsigned int shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);
    // check for linking errors
    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &amp;success);
    if (!success) {
        glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
        std::cout &lt;&lt; &quot;ERROR::SHADER::PROGRAM::LINKING_FAILED\n&quot; &lt;&lt; infoLog &lt;&lt; std::endl;
    }
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

    shaderPrograms.push_back(shaderProgram);

}
</code></pre>
<p>CglSolidModel.cpp</p>
<pre><code>CglSolidModel::CglSolidModel() {

}

CglSolidModel::~CglSolidModel() {

}

void CglSolidModel::loadModels(glm::vec3 vertices[], unsigned int indices[]) {

    glGenVertexArrays(1, &amp;VAO);
    glGenBuffers(1, &amp;VBO);
    glGenBuffers(1, &amp;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, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)nullptr);
    glEnableVertexAttribArray(0);

    // note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    // remember: do NOT unbind the EBO while a VAO is active as the bound element buffer object IS stored in the VAO; keep the EBO bound.
    //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    // You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
    // VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
    glBindVertexArray(1);


    // uncomment this call to draw in wireframe polygons.
    //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

}

void CglSolidModel::bind(unsigned int shaderProgram) {

    // draw our first triangle
    glUseProgram(shaderProgram);
    glBindVertexArray(VAO); // seeing as we only have a single VAO there's no need to bind it every time, but we'll do so to keep things a bit more organized
    //glDrawArrays(GL_TRIANGLES, 0, 6);
    glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0);
    // glBindVertexArray(0); // no need to unbind it every time

}
</code></pre>
<p>Im creating the VBO, EBO and VBA inside each SolidModel.</p>
<p><a href="https://i.sstatic.net/EmiYD.png" rel="nofollow noreferrer">Only two lines for two different triangles with GL_LINE</a></p>

<opengl><c++>
My OpenGL program is not drawing filled polygons
Yair Camborda Morocho
# My OpenGL program is not drawing filled polygons

(Asked by: username_0 on 2021-03-11)

I'm trying to learn OpenGL in c++ (I used it in Java) but I have a problem, I make a triangle, but it doesn't draw on GL\_FILL and in GL\_LINE it just draw a line, I can't find my mistake, I guess my bug is in vertex buffers, but I can't detect it, can anyone help me please?

CglApp.cpp:

```
    CglApp::CglApp() {

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

    glm::vec3 vertices2[] = {
            //{0.5f,  0.5f, 0.0f} ,  // top right
            {0.5f, -0.5f, 0.0f},  // bottom right
            {-0.5f, -0.5f, 0.0f},  // bottom left
            {-0.5f,  0.5f, 0.0f}   // top left
    };

    unsigned int indices2[] = {  // note that we start from 0!
            //0, 1, 3,  // first Triangle
            1, 2, 3   // second Triangle
    };

    cglSolidModel.loadModels(vertices,indices);
    cglSolidModel1.loadModels(vertices2,indices2);

}

CglApp::~CglApp() {

}

void CglApp::run() {

    while (!cglWindow.shouldClose()){

        // input
        // -----
        inputManager.processInput(cglWindow.getWindow());

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

        cglSolidModel.bind(cglShaders.getDefaultShader());
        cglSolidModel1.bind(cglShaders.getDefaultShader());

        // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
        // -------------------------------------------------------------------------------
        glfwSwapBuffers(cglWindow.getWindow());
        glfwPollEvents();

    }

}

```

CglShaders.cpp

```
CglShaders::CglShaders() {
    createDefaultShader();
}

CglShaders::~CglShaders() {

}

void CglShaders::createDefaultShader() {

    const char *vertexShaderSource = "#version 330 core\n"
                                     "layout (location = 0) in vec3 aPos;\n"
                                     "void main()\n"
                                     "{\n"
                                     "   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
                                     "}\0";
    const char *fragmentShaderSource = "#version 330 core\n"
                                       "out vec4 FragColor;\n"
                                       "void main()\n"
                                       "{\n"
                                       "   FragColor = vec4(1.0f, 0.9f, 0.2f, 1.0f);\n"
                                       "}\n\0";

    createShader(vertexShaderSource,fragmentShaderSource);

}

void CglShaders::createShader(const char *vertexShaderSource, const char *fragmentShaderSource) {

    // build and compile our shader program
    // ------------------------------------
    // vertex shader
    unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vertexShader);
    // check for shader compile errors
    int success;
    char infoLog[512];
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
    if (!success)
    {
        glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
        std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
    }
    // fragment shader
    unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fragmentShader);
    // check for shader compile errors
    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
    if (!success)
    {
        glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
        std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
    }
    // link shaders
    unsigned int shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);
    // check for linking errors
    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
    if (!success) {
        glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
        std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
    }
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

    shaderPrograms.push_back(shaderProgram);

}

```

CglSolidModel.cpp

```
CglSolidModel::CglSolidModel() {

}

CglSolidModel::~CglSolidModel() {

}

void CglSolidModel::loadModels(glm::vec3 vertices[], unsigned int indices[]) {

    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, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)nullptr);
    glEnableVertexAttribArray(0);

    // note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    // remember: do NOT unbind the EBO while a VAO is active as the bound element buffer object IS stored in the VAO; keep the EBO bound.
    //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    // You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
    // VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
    glBindVertexArray(1);

    // uncomment this call to draw in wireframe polygons.
    //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

}

void CglSolidModel::bind(unsigned int shaderProgram) {

    // draw our first triangle
    glUseProgram(shaderProgram);
    glBindVertexArray(VAO); // seeing as we only have a single VAO there's no need to bind it every time, but we'll do so to keep things a bit more organized
    //glDrawArrays(GL_TRIANGLES, 0, 6);
    glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0);
    // glBindVertexArray(0); // no need to unbind it every time

}

```

Im creating the VBO, EBO and VBA inside each SolidModel.

[Only two lines for two different triangles with GL\_LINE](https://i.sstatic.net/EmiYD.png)

**Tags:** opengl, c++


---

## 1 answers

### Answer by username_1 on 2021-03-12. Score: 3

A problem I see in your code is that you take the `sizeof()` an unsized array, which yields the size of the *pointer* to that array and not the size of array itself.

```
void CglSolidModel::loadModels(glm::vec3 vertices[], unsigned int indices[]) {
{
    ...
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    ...
}

```

Here is a small test case that demonstrates the issue.

```
void func(int array[]) {
    printf("sizeof(array) = %d\n", sizeof(array));
}

int myArray[10];
func(myArray);

```

Output when compiled for x64:

```
sizeof(array) = 8  

```

This is the size of the 64bit pointer to the array. You would expect 10\*sizeof(int) = 40. In your code (assuming x64) it only sends 8 bytes of the vertice array to the VBO, which is enough to fill the XY coordinates for the first vertex. That goes some way to explaining why you only see 1 partial triangle.

It's not possible for C++ to determine the size of an unsized array. In C++ `int array[];` is equivalent to `const int *array;` and so `sizeof(array)` is the same in both cases. This isn't the case for sized arrays, `int array[10];` would give you 40 bytes as you would expect.

I would recommend you pass another parameter which contains the size of the array or use a container like `std::vector` which stores the size along with the array. Be aware that `std::vector` returns the number of elements and not the number of bytes which `glBufferData` expects.

> **Comments:**
> **username_0**: Oh I understand, thanks so much, I'm gonna use sizeof(vertices[0])*vertexCount in this case.  
> **username_1**: Happy to help. One small thing I noticed in your code was glBindVertexArray(1) after your VAO/VBO is loaded - What is object #1? Usually glBindVertexArray(0) is used to unbind VAO to openGL. Infact the call glBindBuffer(GL_ARRAY_BUFFER, 0); looks risky as you still have your VAO bound, I would suggest a call to glBindVertexArray(0) is all that is needed after initialisation, this will leave your VAO in its setup state  

---

