After glClearBufferSubData I can't draw

With the following strcuture in the logic:

  1. Generate VAO and bind it
  2. Generate Buffer and bind it
  3. Fill data into buffer
  4. Create and use program (the shader)
  5. DrawArrays.

I can draw as spected, but, if add a 3.5 point, between 3 and 4, using glClearBufferSubData, the program dont draw anymore.

I tried other approach like call glClearBufferSubData in random moment (when I press one key of the keyboard) and the program neither doesn not work.

glClearBufferSubData function itself works as I spected I think, when I call glGetBufferSubData the data received is the spected and OpenGL don’t throw any error with glGetError().:

The static global declarations are:

static GLfloat vertices_pos1[] = {
        1.0f,-1.0f,0.0f  ,
        -1.0f,-1.0f,0.0f  ,
        0.0f,1.0f,0.0f
};

static GLfloat vertices_pos2[] = {
        -0.5f, -0.5f, 0.0f, // left
        0.5f, -0.5f, 0.0f, // right
        0.0f,  0.5f, 0.0f  // top
};

static const char* vertexSource =
        "#version 430 core\n"
        "layout (location = 0) in vec3 pos;\n"
        "void main() {\n"
        "   gl_Position = vec4(pos, 1.0);\n"
        "}\n";

static const char* fragmentSource =
        "#version 430 core\n"
        "out vec4 outColor;\n"
        "void main() {\n"
        "   outColor = vec4(1.0, 0.0, 0.0, 1.0);"
        "}\n";

In the startup stage I do:

        glClearColor(0.0f, 0.1f, 0.2f, 0.0);
        program = shader::createPorgramFromString(vertexSource, fragmentSource);

        glGenVertexArrays(1, &vao);
        glBindVertexArray(vao);

        glGenBuffers(1, &vbo);
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glBufferData(GL_ARRAY_BUFFER, sizeof(float)*9, vertices_pos1, GL_STATIC_DRAW);

        glClearBufferSubData(GL_ARRAY_BUFFER, GL_RGB32F, 0, sizeof(vertices_pos2), GL_RGB, GL_FLOAT, vertices_pos2);
        float o[9];
        glGetBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices_pos1), o);
        
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float)*3, 0);
        glEnableVertexAttribArray(0);

        glUseProgram(program);

And in the render stage I do:

    glClear(GL_COLOR_BUFFER_BIT);
    glDrawArrays(GL_TRIANGLES, 0, 3);

The lines glClearBufferSubData and glGetBufferSubdata said me that the new data is correct, but OpenGL doesn’t draw anything.

If I resend the same data (put again vertices_pos1 instead vertices_pos2) the program neither doesn’t work.

The only way to get the triangle is comment the line glClearBufferSubData.

Anybody can light me a little in this? Thanks :slight_smile:

Define “correct”. Your code strongly suggests a misunderstanding of what glClearBufferSubData is doing.

As the name suggests, it exists to clear the buffer of its existing data. The only reason why it takes a pointer to a value is so that you can provide a “cleared” value, which will be repeatedly copied to every byte in the range of the buffer. It’s like memset for buffer objects.

Specifically, it computes the value to copy over the buffer as if by doing a pixel transfer operation from the given values to the given internal format. Your internal format was GL_RGB32F, so it will copy 12 bytes repeatedly into the total range given. The pixel transfer format and type of GL_RGB and GL_FLOAT respectively mean that the data provided by the pointer defines a “pixel” as a sequence of 3 values of type float. Which you provide.

But clearing a buffer only copies a single “pixel”'s worth of data. So you’re only taking the first three floats from vertices_pos2, which will be repeatedly copied over the buffer range. Well, this sets all of the positions to the same value. A triangle where each position is at the same location has no area, and therefore is not rendered.

It’s not clear exactly what you’re intending to do, but it is apparent that clearing the buffer is not it.

Of course not; your glGetBufferSubData overwrote vertices_pos1. You can’t resend it because you lost it.

Thank you so much, now its pretty much more clear the intention of glClearBufferSubData :slight_smile:

I thoght that was more like glBufferData, but with other approach (like much other multiple approach to do the same thing in OpenGL) and only tried to play with it. Nothinig specific than to redraw the triangle like I can do with glBufferData.

Thanks you again!