C++, OpengGL animation how to change the color of the cubes when the line is moving?

I have this OpenGL program in C++ which is a moving circle, vubes in the background and a line which can move up or down is you press the W or the S button. When the line is in the middle of the screen the cubes which are below the line should have green color, and for the cubes above the line the color should be red.

When the line is moved up the color of the cubes should change, so when the line is in the top of the scrren every cube needs to be red.

In my code when I move the Line up it changes his color when it needs to be but the cubes has the color from the beginning of the run to the end, no matter where I move the line.

Attaching the code:

  #include <GL/glew.h>
#include <GLFW/glfw3.h>

#include "glm/glm.hpp"

#include <array>
#include <vector>
#include <iostream>
#include <string>
#include <fstream>
#include <math.h>

#define COORDMIN -0.7
#define COORDMAX  0.7
#define PI 3.14159265359
using namespace std;


GLuint VBO;
GLuint VAO;

GLuint VBO1;
GLuint VAO1;

GLuint VBO2;
GLuint VAO2;

static int WIN_WIDTH = 600;
static int WIN_HEIGHT = 600;


float x = 0.0f;
float y = 0.0f;
float inc = 0.01f;
float inc1 = 0.01f;

bool up = true;
bool down = false;

float fel = 1.0f;
float le = -1.0f;

bool xDir = true;
bool yDir = false;
bool go = true;

GLfloat p;

std::vector<glm::vec3> linePoints;

glm::vec3 vertices[] = {

    glm::vec3(-0.9f,  0.9f, 0.0f),  glm::vec3(1.0f, 1.0f, 1.0f),//sor1
    glm::vec3(-0.7f,  0.9f, 0.0f),  glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(-0.5f,  0.9f, 0.0f),  glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(-0.3f,  0.9f, 0.0f),  glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(-0.1f,  0.9f, 0.0f),  glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.1f,  0.9f, 0.0f),  glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.3f,  0.9f, 0.0f),  glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.5f,  0.9f, 0.0f),  glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.7f,  0.9f, 0.0f),  glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.9f,  0.9f, 0.0f),  glm::vec3(1.0f, 1.0f, 1.0f),//sor1

    glm::vec3(-0.9f,  0.7f, 0.0f),  glm::vec3(1.0f, 1.0f, 1.0f),//sor 2
    glm::vec3(-0.7f,  0.7f, 0.0f),  glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(-0.5f,  0.7f, 0.0f),  glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(-0.3f,  0.7f, 0.0f),  glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(-0.1f,  0.7f, 0.0f),  glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.1f,  0.7f, 0.0f),  glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.3f,  0.7f, 0.0f),  glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.5f,  0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.7f,  0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.9f,  0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),//sor 2

    glm::vec3(-0.9f,  0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),  //sor 3
    glm::vec3(-0.7f,  0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(-0.5f,  0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(-0.3f,  0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(-0.1f,  0.5, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.1f,  0.5, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.3f,  0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.5f,  0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.7f,  0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.9f,  0.5, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),//sor 3

    glm::vec3(-0.9f,  0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),  //sor 4
    glm::vec3(-0.7f,  0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(-0.5f,  0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(-0.3f,  0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(-0.1f,  0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.1f,  0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.3f,  0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.5f,  0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.7f,  0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.9f,  0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),//sor 4

    glm::vec3(-0.9f,  0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),  //sor 5
    glm::vec3(-0.7f,  0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(-0.5f,  0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(-0.3f,  0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(-0.1f,  0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.1f,  0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.3f,  0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.5f,  0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.7f,  0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.9f,  0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), //sor 5

    glm::vec3(-0.9f,  -0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),  //sor 6
    glm::vec3(-0.7f,  -0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(-0.5f,  -0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(-0.3f,  -0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(-0.1f,  -0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.1f,  -0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.3f,  -0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.5f,  -0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.7f,  -0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.9f,  -0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),//sor 6

    glm::vec3(-0.9f,  -0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), //sor 7
    glm::vec3(-0.7f,  -0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(-0.5f,  -0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(-0.3f,  -0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(-0.1f,  -0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.1f,  -0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.3f,  -0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.5f,  -0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.7f,  -0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.9f,  -0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),//sor 7

    glm::vec3(-0.9f,  -0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), //sor 8
    glm::vec3(-0.7f,  -0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(-0.5f,  -0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(-0.3f,  -0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(-0.1f,  -0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.1f,   -0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.3f,    -0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.5f,   -0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.7f,   -0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.9f,   -0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),//sor 8

    glm::vec3(-0.9f,  -0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),  //sor 9
    glm::vec3(-0.7f,  -0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(-0.5f,  -0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(-0.3f,  -0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(-0.1f,  -0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.1f,   -0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.3f,   -0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.5f,   -0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.7f,   -0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.9f,   -0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),//sor 9

    glm::vec3(-0.9f,  -0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),  //sor 9
    glm::vec3(-0.7f,  -0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(-0.5f,  -0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(-0.3f,  -0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(-0.1f,  -0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.1f,   -0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.3f,   -0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.5f,   -0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.7f,   -0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
    glm::vec3(0.9f,   -0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),//sor 9

};

float a = 0.0f;
float b = 0.95f;
float b1 = -0.95f;

glm::vec3 vertices2[4];

void genSzakasz(float a) {

    vertices2[0] = glm::vec3(-1.0f, a, 0.0f);
    vertices2[1] = glm::vec3(1.0f, a, 0.0f);
    vertices2[2] = glm::vec3(1.0f, 1.0f, 0.0f);
    vertices2[3] = glm::vec3(1.0f, 1.0f, 0.0f);
}


float RandomCoordGenerator()
{
    float r3 = COORDMIN + static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / (COORDMAX - COORDMIN)));
    return r3;
}

GLfloat radius = 0.2f;                      // first
GLfloat centerx = RandomCoordGenerator();
GLfloat centery = RandomCoordGenerator();
GLfloat novX = 0.002f;
GLfloat novY = 0.005f;
GLdouble updateFrequency = 0.01f, lastUpdate;

void korSzin()
{
    for (int i = 0; i < 100; i++)
    {
        linePoints.push_back(
            glm::vec3(
                0.0f, 1.0f, 0.0f));
    }
}

void generatePoints()
{

    for (int i = 0; i < 100; i++)
    {
        linePoints.push_back(
            glm::vec3(
                centerx + radius * cos(i * (2 * 3.14159 / 100)),
                centery + radius * sin(i * (2 * 3.14159 / 100)),
                0));
    }
    korSzin();
}



GLuint renderingProgram; //kor
GLuint renderingProgram2; //pontok 
GLuint renderingProgram3; //szakasz

bool checkOpenGLError() {
    bool foundError = false;
    int glErr = glGetError();
    while (glErr != GL_NO_ERROR) {
        cout << "glError: " << glErr << endl;
        foundError = true;
        glErr = glGetError();
    }
    return foundError;
}

void printShaderLog(GLuint shader) {
    int len = 0;
    int chWrittn = 0;
    char* log;
    glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
    if (len > 0) {
        log = (char*)malloc(len);
        glGetShaderInfoLog(shader, len, &chWrittn, log);
        cout << "Shader Info Log: " << log << endl;
        free(log);
    }
}

void printProgramLog(int prog) {
    int len = 0;
    int chWrittn = 0;
    char* log;
    glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &len);
    if (len > 0) {
        log = (char*)malloc(len);
        glGetProgramInfoLog(prog, len, &chWrittn, log);
        cout << "Program Info Log: " << log << endl;
        free(log);
    }
}

string readShaderSource(const char* filePath) {
    string content;
    ifstream fileStream(filePath, ios::in);
    string line = "";

    while (!fileStream.eof()) {
        getline(fileStream, line);
        content.append(line + "n");
    }
    fileStream.close();
    return content;
}

GLuint createShaderProgram() {

    GLint vertCompiled;
    GLint fragCompiled;
    GLint linked;

    
    
        string vertShaderStr = readShaderSource("vertexShader.glsl");
        string fragShaderStr = readShaderSource("fragmentShader.glsl");

        GLuint vShader = glCreateShader(GL_VERTEX_SHADER);
        GLuint fShader = glCreateShader(GL_FRAGMENT_SHADER);

        const char* vertShaderSrc = vertShaderStr.c_str();
        const char* fragShaderSrc = fragShaderStr.c_str();

        glShaderSource(vShader, 1, &vertShaderSrc, NULL);
        glShaderSource(fShader, 1, &fragShaderSrc, NULL);

        glCompileShader(vShader);
        glCompileShader(vShader);
        checkOpenGLError();
        glGetShaderiv(vShader, GL_COMPILE_STATUS, &vertCompiled);
        if (vertCompiled != 1) {
            cout << "vertex compilation failed" << endl;
            printShaderLog(vShader);
        }


        glCompileShader(fShader);
        checkOpenGLError();
        glGetShaderiv(vShader, GL_COMPILE_STATUS, &fragCompiled);
        if (fragCompiled != 1) {
            cout << "fragment compilation failed" << endl;
            printShaderLog(fShader);
        }

        
        GLuint vfProgram = glCreateProgram();
        glAttachShader(vfProgram, vShader);
        glAttachShader(vfProgram, fShader);

        glLinkProgram(vfProgram);
        checkOpenGLError();
        glGetProgramiv(vfProgram, GL_LINK_STATUS, &linked);
        if (linked != 1) {
            cout << "linking failed" << endl;
            printProgramLog(vfProgram);
        }

        glDeleteShader(vShader);
        glDeleteShader(fShader);

        return vfProgram;
}

void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    float szakasz_y_koord = 0.0f;
    if (key == GLFW_KEY_W && action == GLFW_PRESS)
    {


        if (a <= b) {
            a += 0.2f;
            genSzakasz(a);
            szakasz_y_koord = a;
            GLuint offsetLoc = glGetUniformLocation(renderingProgram, "szakasz_y_koord"); // mutató az "offsetX" értékre
            glProgramUniform1f(renderingProgram, offsetLoc, a);

            glBindBuffer(GL_ARRAY_BUFFER, VBO2);
            glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW);
            glBindBuffer(GL_ARRAY_BUFFER, 0);


        }
    

    }
    if (key == GLFW_KEY_S && action == GLFW_PRESS)
    {
        if (a >= b1) {
            a -= 0.2f;
            genSzakasz(a);
            szakasz_y_koord = a;
            GLuint offsetLoc = glGetUniformLocation(renderingProgram, "szakasz_y_koord"); // mutató az "offsetX" értékre
            glProgramUniform1f(renderingProgram, offsetLoc, a);
            glBindBuffer(GL_ARRAY_BUFFER, VBO2);
            glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW);
            glBindBuffer(GL_ARRAY_BUFFER, 0);
            createShaderProgram();
        }


        genSzakasz(a);
        glBindBuffer(GL_ARRAY_BUFFER, VBO2);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
    }
}



void init(GLFWwindow* window) {
    renderingProgram = createShaderProgram(); // minden mas

    generatePoints();
    
    genSzakasz(a);

    glGenBuffers(1, &VBO);
    glGenVertexArrays(1, &VAO);

    glGenBuffers(1, &VBO1);
    glGenVertexArrays(1, &VAO1);

    glGenBuffers(1, &VBO2);
    glGenVertexArrays(1, &VAO2);

    
    glBindBuffer(GL_ARRAY_BUFFER, VBO);

    glBufferData(GL_ARRAY_BUFFER, 200 * sizeof(glm::vec3), linePoints.data(), GL_STATIC_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    renderingProgram2 = createShaderProgram();
    glBindBuffer(GL_ARRAY_BUFFER, VBO1);
    glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * 200, vertices, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glBindBuffer(GL_ARRAY_BUFFER, VBO2);
    glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * 4, vertices2, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);


    glBindVertexArray(VAO);

    
    glBindBuffer(GL_ARRAY_BUFFER, VBO);


    Elsőként megadjuk ezt az azonosítószámot.
    Utána az attribútum méretét (vec3, láttuk a shaderben).
    Harmadik az adat típusa.
    Negyedik az adat normalizálása, ez maradhat FALSE jelen példában.
    Az attribútum értékek hogyan következnek egymás után? Milyen lépésköz után találom a következő vertex adatait?
    Végül megadom azt, hogy honnan kezdődnek az értékek a pufferben. Most rögtön, a legelejétől veszem őket.*/
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), (void*)0);


    
    glEnableVertexAttribArray(0);


    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), (void*)(100 * sizeof(glm::vec3)));
    glEnableVertexAttribArray(1);

    
    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);


    glBindVertexArray(VAO1);
    glBindBuffer(GL_ARRAY_BUFFER, VBO1);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3) * 2, (void*)0);
    glEnableVertexAttribArray(0);


    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3) * 2, (void*)(sizeof(glm::vec3)));
    glEnableVertexAttribArray(1);

    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glBindVertexArray(VAO2);
    glBindBuffer(GL_ARRAY_BUFFER, VBO2);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), (void*)0);
    glEnableVertexAttribArray(0);

    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), (void*)(2 * sizeof(glm::vec3)));
    glEnableVertexAttribArray(1);

    
    glBindVertexArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

}


void cleanUpScene()
{

    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);

    
    glDeleteProgram(renderingProgram);
}

void bounce(double currentTime) {
    if (currentTime - lastUpdate >= updateFrequency)
    {
        y += inc1;
        x += inc;
        if (x > 1.5f) inc = -0.01; // jobb
        if (x < -0.07f) inc = 0.01; //bal 
        if (y > 0.7f) inc1 = -0.01; // fennt
        if (y < -0.9f) inc1 = 0.01; //lennt
        GLuint offsetLoc = glGetUniformLocation(renderingProgram, "offsetX"); // mutató az "offsetX" értékre
        glProgramUniform1f(renderingProgram, offsetLoc, x); // küldjük el az "x" értékét az "offsetX" számára

        GLuint offsetLoc1 = glGetUniformLocation(renderingProgram, "offsetY"); // mutató az "offsetX" értékre
        glProgramUniform1f(renderingProgram, offsetLoc1, y); // küldjük el az "x" értékét az "offsetX" számára
    }
}

void display(GLFWwindow* window, double currentTime) {

    glClearColor(0.0, 0.0, 0.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT); // fontos lehet minden egyes alkalommal törölni!

    


    glUseProgram(renderingProgram);
    glBindVertexArray(VAO);
    glPointSize(30.0f);
    bounce(glfwGetTime());
    glDrawArrays(GL_TRIANGLE_FAN, 0, 100);
    

    glUseProgram(renderingProgram2);
    glBindVertexArray(VAO1);
    glPointSize(10.0f);
    glDrawArrays(GL_POINTS, 0, 100);



    glUseProgram(renderingProgram2);
    glBindVertexArray(VAO2);
    glPointSize(30.0f);
    glDrawArrays(GL_LINE_LOOP, 0, 2);





    glBindVertexArray(0);
}

int main(void) {



    
    if (!glfwInit()) { exit(EXIT_FAILURE); }


    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);

    
    GLFWwindow* window = glfwCreateWindow(WIN_WIDTH, WIN_HEIGHT, "Draw a Line", NULL, NULL);

    
    glfwMakeContextCurrent(window);

    glfwSetKeyCallback(window, keyCallback);
    //glfwSetCursorPosCallback(window, cursorPosCallback);
    glfwSetMouseButtonCallback(window, mouseButtonCallback);

    
    if (glewInit() != GLEW_OK) { exit(EXIT_FAILURE); }
    glfwSwapInterval(1);


    init(window);

    while (!glfwWindowShouldClose(window)) {
    
        display(window, glfwGetTime());

        glfwSwapBuffers(window);
    
        glfwPollEvents();
    }


    glfwDestroyWindow(window);


    cleanUpScene();

    glfwTerminate();
    exit(EXIT_SUCCESS);
}

Here is my Vertex Shader:

#version 430

uniform float offsetX;
uniform float offsetY;
uniform float szakaszYkoord;

layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 color;

out vec3 myColor;

void main(void)
{
        
    gl_Position = vec4(aPos.x + offsetX, aPos.y + offsetY + szakaszYkoord, aPos.z, 1.0);    

    if ( aPos.y > szakaszYkoord){
        myColor = vec3(1.0, 1.0, 0.0);
    } else {
        myColor = vec3(1.0, 0.0, 0.0);
    }
    
}

Here is my Fragment Shader:

#version 430

in vec3 myColor;

out vec4 color;

void main(void)
{
    color = vec4(myColor, 1.0);
    
}

My question is why the color of the line is changing buts the color of the cubes not? What should I do in order to change the color of the cubes when the line is moving?

Answer

Pass the vertex coordinate from the vertex shader to the fragment shader and set the color per fragment instead of per vertex.

Vertex shader:

#version 430

uniform float offsetX;
uniform float offsetY;

layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 color;

out vec3 vPos;

void main(void)
{
    vPos = aPos + vec3(offsetX, offsetY, 0.0);
    gl_Position = vec4(vPos, 1.0);  
} 

Fragment shader

#version 430

uniform float szakasz_y_koord;

in vec3 vPos;
out vec4 color;

void main(void)
{
    color = (vPos.y > szakasz_y_koord) 
        ? vec4(1.0, 1.0, 0.0, 1.0) 
        : vec4(1.0, 0.0, 0.0, 1.0);
}

Uniform variables are stored in the default uniform block of the shader program. They use the same shader source code to generate 2 programs objects. You only need 1 program and can completely remove the 2nd program.

As long as you are using 2 programs, you have to change the uniform variable in both programs. Set “szakasz_y_koord” to -1.0 when the circle is drawn and set it to a when the dots are drawn:

void display(GLFWwindow* window, double currentTime) {

    glClearColor(0.0, 0.0, 0.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT); // fontos lehet minden egyes alkalommal törölni!

    GLuint offsetLoc = glGetUniformLocation(renderingProgram, "szakasz_y_koord"); // mutató az "offsetX" értékre
    glProgramUniform1f(renderingProgram, offsetLoc, -1.0);

    glUseProgram(renderingProgram);
    glBindVertexArray(VAO);
    glPointSize(30.0f);
    bounce(glfwGetTime());
    glDrawArrays(GL_TRIANGLE_FAN, 0, 100);

    GLuint offsetLoc2 = glGetUniformLocation(renderingProgram, "szakasz_y_koord"); // mutató az "offsetX" értékre
    glProgramUniform1f(renderingProgram2, offsetLoc2, a);

    glUseProgram(renderingProgram2);
    glBindVertexArray(VAO1);
    glPointSize(10.0f);
    glDrawArrays(GL_POINTS, 0, 100);

    glBindVertexArray(VAO2);
    glPointSize(30.0f);
    glDrawArrays(GL_LINE_LOOP, 0, 2);

    glBindVertexArray(0);
}