Is there a way I can make this easier for openGL to draw? I have a very basic grasp of computer graphics however I threw it all away when I wrote this simple application that I am using for scientific purposes. I didn't have a lot of time to write it correctly because my "bosses" didn't see the promise of it but now that it is done they have found it quite useful.

The problem is I built it stupidly.

Basically it takes a TON of points stored in a big array and draws them to the screen. The screen can be moved and zoomed.

Instead of using a matrix to accomplish this I am simply passing in the width, height and center of the screen making my average vertex shader look like so

#version 330 core
layout (location = 0) in float ex;
layout (location = 1) in float ey;

uniform float sizeX;
uniform float sizeY;
uniform float centerX;
uniform float centerY;
uniform float size;

out vec4 color;
out float passsize;
void main()
{
    gl_PointSize = size;
    passsize = size;
    float x = (ex - centerX) / (sizeX / 2.0);
    float y = (ey - centerY) / (sizeY / 2.0);
    gl_Position = vec4(x, y, 0.0, 1.0);

    color = vec4(1.0f, 0.5f, 0.2f, 1.0f);
}


and an average draw call look about like this

glUseProgram(program);
glGenVertexArrays(1, &amp;VAO1);
glBindVertexArray(VAO1);

glGenBuffers(1, &amp;VBO1);
glBindBuffer(GL_ARRAY_BUFFER, VBO1);
glBufferData(GL_ARRAY_BUFFER, sizeof(data1), data1, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, VBO1);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);

glBindBuffer(GL_ARRAY_BUFFER, 0);

glGenBuffers(1, &amp;VBO2);
glBindBuffer(GL_ARRAY_BUFFER, VBO2);
glBufferData(GL_ARRAY_BUFFER, sizeof(data2), data2, GL_STATIC_DRAW);
glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);

glUniform1f(glGetUniformLocation(program, "centerX"), centerX);
glUniform1f(glGetUniformLocation(program, "centerY"), centerY);
glUniform1f(glGetUniformLocation(program, "sizeX"), scrwidth);
glUniform1f(glGetUniformLocation(program, "sizeY"), scrheight);
glUniform1f(glGetUniformLocation(program, "size"), dotSize);

glDrawArrays(GL_POINTS, 0, dot count);
glfwSwapBuffers(window);
glfwPollEvents();


This works very well but I would love to get rid of the low frame rate this causes when I am drawing a ton of points (generally over 10,000 on my small laptop that doesn't actually have a GPU).

Is there any way I can get the GPU to more intelligently clip points that are going to be off screen?

I don't have a lot of time to change things around so it would be great if it were something simple to achieve.
You only need to create the VBOs and VAO once and then you can reuse them every frame.

void init(){

    glGenVertexArrays(1, &amp;VAO1);
    glBindVertexArray(VAO1);

    glGenBuffers(1, &amp;VBO1);
    glBindBuffer(GL_ARRAY_BUFFER, VBO1);
    glBufferData(GL_ARRAY_BUFFER, sizeof(data1), data1, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, VBO1);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glGenBuffers(1, &amp;VBO2);
    glBindBuffer(GL_ARRAY_BUFFER, VBO2);
    glBufferData(GL_ARRAY_BUFFER, sizeof(data2), data2, GL_STATIC_DRAW);
    glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(1);

    uniformLoc_centerX = glGetUniformLocation(program, "centerX");
    uniformLoc_centerY = glGetUniformLocation(program, "centerY");
    uniformLoc_sizeX = glGetUniformLocation(program, "sizeX");
    uniformLoc_sizeY = glGetUniformLocation(program, "sizeY");
    uniformLoc_size= glGetUniformLocation(program, "size");
}

void draw(){
    glUseProgram(program);
    glBindVertexArray(VAO1);

    glUniform1f(uniformLoc_centerX, centerX);
    glUniform1f(uniformLoc_centerY, centerY);
    glUniform1f(uniformLoc_sizeX, scrwidth);
    glUniform1f(uniformLoc_sizeY, scrheight);
    glUniform1f(uniformLoc_size, dotSize);

    glDrawArrays(GL_POINTS, 0, dot count);
}


If the data ever changes then all you need to do is:

glGenBuffers(1, &amp;VBO1);
glBufferData(GL_ARRAY_BUFFER, sizeof(data1), data1, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, VBO2);
glBufferData(GL_ARRAY_BUFFER, sizeof(data2), data2, GL_STATIC_DRAW);