Cube rendering with OpenGL ES 2.0

I’m trying to render a cube on my embedded system using OpenGL ES. All other aspects related to the context are working; however, when I set up the graphics functions or render frames for a 3D object, no figure is drawn, and the colors from the faces of the cube cover the whole screen.
I would like to know what I’m doing wrong…

static const GLfloat vVertices[] = {
    -0.5f, -0.5f, -0.5f,  // front
    -0.5f, -0.5f,  0.5f,
    0.5f, -0.5f,  0.5f,
    0.5f, -0.5f, -0.5f,

    -0.5f,  0.5f, -0.5f, // back
    -0.5f,  0.5f,  0.5f,
    0.5f,  0.5f,  0.5f,
    0.5f,  0.5f, -0.5f,

    -0.5f, -0.5f, -0.5f, // right
    -0.5f,  0.5f, -0.5f,
    0.5f,  0.5f, -0.5f,
    0.5f, -0.5f, -0.5f,

    -0.5f, -0.5f, 0.5f, // left
    -0.5f,  0.5f, 0.5f,
    0.5f,  0.5f, 0.5f, 
    0.5f, -0.5f, 0.5f,

    -0.5f, -0.5f, -0.5f, // top
    -0.5f, -0.5f,  0.5f,
    -0.5f,  0.5f,  0.5f,
    -0.5f,  0.5f, -0.5f,

    0.5f, -0.5f, -0.5f, // bottom
    0.5f, -0.5f,  0.5f,
    0.5f,  0.5f,  0.5f,
    0.5f,  0.5f, -0.5f
};

static const GLfloat vColors[] = {
    0.0f, 1.0f, 0.0f, // front
    0.0f, 1.0f, 0.0f,
    0.0f, 1.0f, 0.0f,
    0.0f, 1.0f, 0.0f,

    0.0f, 1.0f, 0.0f, // back
    0.0f, 1.0f, 0.0f,
    0.0f, 1.0f, 0.0f,
    0.0f, 1.0f, 0.0f,

    1.0f, 0.0f, 0.0f, // right
    1.0f, 0.0f, 0.0f,
    1.0f, 0.0f, 0.0f,
    1.0f, 0.0f, 0.0f,

    1.0f, 0.0f, 0.0f, // left
    1.0f, 0.0f, 0.0f,
    1.0f, 0.0f, 0.0f,
    1.0f, 0.0f, 0.0f,

    0.0f, 0.0f, 1.0f, // top
    0.0f, 0.0f, 1.0f,
    0.0f, 0.0f, 1.0f,
    0.0f, 0.0f, 1.0f,

    0.0f, 0.0f, 1.0f, // bottom
    0.0f, 0.0f, 1.0f,
    0.0f, 0.0f, 1.0f,
    0.0f, 0.0f, 1.0f
};

static const GLfloat vNormals[] = {
    0.0f,  0.0f,  1.0f,
    0.0f,  0.0f,  1.0f,
    0.0f,  0.0f,  1.0f,
    0.0f,  0.0f,  1.0f,

    0.0f,  0.0f, -1.0f,
    0.0f,  0.0f, -1.0f,
    0.0f,  0.0f, -1.0f,
    0.0f,  0.0f, -1.0f,

    1.0f,  0.0f,  0.0f,
    1.0f,  0.0f,  0.0f,
    1.0f,  0.0f,  0.0f,
    1.0f,  0.0f,  0.0f,

   -1.0f,  0.0f,  0.0f,
   -1.0f,  0.0f,  0.0f,
   -1.0f,  0.0f,  0.0f,
   -1.0f,  0.0f,  0.0f,

    0.0f,  1.0f,  0.0f,
    0.0f,  1.0f,  0.0f,
    0.0f,  1.0f,  0.0f,
    0.0f,  1.0f,  0.0f,

    0.0f, -1.0f,  0.0f,
    0.0f, -1.0f,  0.0f,
    0.0f, -1.0f,  0.0f,
    0.0f, -1.0f,  0.0f
};

static const GLfloat vTexCoord[] = {
    0.0f, 0.0f,
    0.0f, 1.0f,
    1.0f, 1.0f,

    1.0f, 0.0f,
    1.0f, 0.0f,
    1.0f, 1.0f,

    0.0f, 1.0f,
    0.0f, 0.0f,
    0.0f, 0.0f,

    0.0f, 1.0f,
    1.0f, 1.0f,
    1.0f, 0.0f,

    0.0f, 0.0f,
    0.0f, 1.0f,
    1.0f, 1.0f,

    1.0f, 0.0f,
    0.0f, 0.0f,
    0.0f, 1.0f,

    1.0f, 1.0f,
    1.0f, 0.0f,
    0.0f, 0.0f,

    0.0f, 1.0f,
    1.0f, 1.0f,
    1.0f, 0.0f,
};

bool InitializeGL(){
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);

    GLintptr positionoffset = 0;
    GLintptr coloroffset = sizeof(vVertices);
    GLintptr normaloffset = sizeof(vVertices) + sizeof(vColors);
    GLintptr texcoordoffset = sizeof(vVertices) + sizeof(vColors) + sizeof(vNormals);

    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, 
                sizeof(vVertices) + sizeof(vColors) + sizeof(vNormals) + sizeof(vTexCoord), 0,
                GL_STATIC_DRAW);
    glBufferSubData(GL_ARRAY_BUFFER, positionoffset, sizeof(vVertices),
                    &vVertices[0]);
    glBufferSubData(GL_ARRAY_BUFFER, coloroffset, sizeof(vColors), &vColors[0]);
    glBufferSubData(GL_ARRAY_BUFFER, normaloffset, sizeof(vNormals),
                    &vNormals[0]);
    glBufferSubData(GL_ARRAY_BUFFER, texcoordoffset, sizeof(vTexCoord),
                    &vTexCoord[0]);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0,
                            (const void*)positionoffset);
    glEnableVertexAttribArray(0);

    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 
                            (const void*)normaloffset);
    glEnableVertexAttribArray(1);

    glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0,
                            (const void*)coloroffset);
    glEnableVertexAttribArray(2);

    glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, 0,
                            (const void*) texcoordoffset);
    glEnableVertexAttribArray(3);

    glClearColor(.0, 0.0, 0.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);
    return true;
}


bool InitializeGLProgram(){
    static const char* vertexShaderSource =
        "uniform mat4 modelviewMatrix;      \n"
        "uniform mat4 modelviewprojectionMatrix;\n"
        "uniform mat3 normalMatrix;         \n"
        "                                   \n"
        "attribute vec4 in_position;        \n"
        "attribute vec3 in_normal;          \n"
        "attribute vec4 in_color;           \n"
        "attribute vec2 in_texCoord;        \n"
        "                                   \n"
        "vec4 lightSource = vec4(2.0, 2.0, 20.0, 0.0);\n"
        "                                   \n"
        "varying vec4 vVaryingColor;        \n"
        "varying float vVaryingDiff;        \n"
        "varying vec2 vTexCoord;            \n"
        "                                   \n"
        "void main(){                        \n"
        "    gl_Position = modelviewprojectionMatrix * in_position;\n"
        "    vec3 vEyeNormal = normalMatrix * in_normal;\n"
        "    vec4 vPosition4 = modelviewMatrix * in_position;\n"
        "    vec3 vPosition3 = vPosition4.xyz / vPosition4.w;\n"
        "    vec3 vLightDir = normalize(lightSource.xyz - vPosition3);\n"
        "    vVaryingDiff = max(0.0, dot(vEyeNormal, vLightDir));\n"
        "    vVaryingColor = in_color;\n"
        "    vTexCoord = in_texCoord;       \n"
        "}                                  \n";

    static const char* fragmentShaderSource =
        "precision mediump float;           \n"
        "                                   \n"
        "varying vec4 vVaryingColor;        \n"
        "varying float vVaryingDiff;        \n"
        "varying vec2 vTexCoord;            \n"
        "                                   \n"
        "void main(){                       \n"
        "    gl_FragColor = vec4(vVaryingDiff * vVaryingColor.rgb, 1.0);\n"
        "}                                  \n";

    vertex_shader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertex_shader, 1, &vertexShaderSource, NULL);
    glCompileShader(vertex_shader);

    GLint ret = 0;
    glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &ret);
    if (!ret){
        printf("vertex shader compilation failed!:\n");
        glGetShaderiv(vertex_shader, GL_INFO_LOG_LENGTH, &ret);

        if (ret > 1){
            char* log = malloc(sizeof(char) * ret);
            glGetShaderInfoLog(vertex_shader, ret, NULL, log);
            printf("%s\n", log);
            free(log);
        }
        return false;
    }

    fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragment_shader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fragment_shader);

    glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &ret);
    if (!ret){
        printf("fragment shader compilation failed!:\n");
        glGetShaderiv(fragment_shader, GL_INFO_LOG_LENGTH, &ret);
        if (ret > 1){
            char* log = malloc(sizeof(char) * ret);
            glGetShaderInfoLog(fragment_shader, ret, NULL, log);
            printf("%s\n", log);
            free(log);
        }
        return false;
    }

    program = glCreateProgram();

    glAttachShader(program, fragment_shader);
    glAttachShader(program, vertex_shader);

    glBindAttribLocation(program, 0, "in_position");
    glBindAttribLocation(program, 1, "in_normal");
    glBindAttribLocation(program, 2, "in_color");
    glBindAttribLocation(program, 3, "in_texCoord");

    glLinkProgram(program);

    glGetProgramiv(program, GL_LINK_STATUS, &ret);
    if (!ret){
        printf("program linking failed!:\n");
        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &ret);
        if (ret > 1){
            char* log = malloc(sizeof(char) * ret);
            glGetProgramInfoLog(program, ret, NULL, log);
            printf("%s\n", log);
            free(log);
        }
        return false;
    }

    glDeleteShader(vertex_shader);
    glDeleteShader(fragment_shader);

    glUseProgram(program);
    mvp_matrix = glGetUniformLocation(program, "modelviewprojectionMatrix");
    if(mvp_matrix == -1) printf("Erro: Uniforme modelviewprojectionMatrix não encontrado!\n");

    mv_matrix = glGetUniformLocation(program, "modelviewMatrix");
    if(mv_matrix == -1) printf("Erro: Uniforme modelviewMatrix não encontrado!\n");

    normal_matrix = glGetUniformLocation(program, "normalMatrix");
    if(normal_matrix == -1) printf("Erro: Uniforme normalMatrix não encontrado!\n");
    if(mvp_matrix == -1 || mv_matrix == -1 || normal_matrix == -1){
        fprintf(stderr, "Erro: Uniforme não encontrado!\n");
        return false;
    } 
    
    return true;
}


void esDraw(EGLDisplay display, EGLSurface surface){
    for (int frame = 0; frame < 600; frame++){
        static float totalTime = 0.0f;  // Acumulador de tempo
        static struct timespec lastTime;
        struct timespec currentTime;
        
        static bool firstCall = true;
        if (firstCall) {
            clock_gettime(CLOCK_MONOTONIC, &lastTime);
            firstCall = false;
        }
        
        clock_gettime(CLOCK_MONOTONIC, &currentTime);
        float deltaTime = (currentTime.tv_sec - lastTime.tv_sec) + 
                        (currentTime.tv_nsec - lastTime.tv_nsec) / 1e9f;
        lastTime = currentTime;
        totalTime += deltaTime;

        float progress = fmod(totalTime, 10.0f) / 10.0f;
        float red = pow(cos(M_PI * 2 * progress), 2) / 3;
        float green = pow(cos(M_PI * 2 * (progress + 0.33f)), 2) / 3;
        float blue = pow(cos(M_PI * 2 * (progress + 0.66f)), 2) / 3;
        glClearColor(red, green, blue, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        float rotationSpeed = 0.5f;  // Graus por segundo
        float rotationAngle = totalTime * rotationSpeed;

        ESMatrix modelview;
        esInitIdentity(&modelview);
        esTranslate(&modelview, 0.0f, 0.0f, -6.0f);
        esRotate(&modelview, 45.0f + rotationAngle * 0.25f, 1.0f, 0.0f, 0.0f);
        esRotate(&modelview, 45.0f - rotationAngle * 0.5f, 0.0f, 1.0f, 0.0f);
        esRotate(&modelview, 10.0f + rotationAngle * 2.0f, 0.0f, 0.0f, 1.0f);
        
        GLfloat aspect =
            (GLfloat)(mode.hdisplay) / (GLfloat)(mode.vdisplay);

        ESMatrix projection;
        float field_of_view = 45.0f;
        esPerspective(&projection, field_of_view, aspect, 1.0f, 20.0f);

        ESMatrix mvp_projection = modelview;
        esMatrixMultiply(&mvp_projection, &projection);

        glUniformMatrix4fv(mv_matrix, 1, GL_FALSE, esData(&modelview));
        glUniformMatrix4fv(mvp_matrix, 1, GL_FALSE, esData(&mvp_projection));

        float normal[9] = {0};
        esGet3x3(&modelview, &normal[0]);
        glUniformMatrix3fv(normal_matrix, 1, GL_FALSE, normal);

        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
        glDrawArrays(GL_TRIANGLE_STRIP, 4, 4);
        glDrawArrays(GL_TRIANGLE_STRIP, 8, 4);
        glDrawArrays(GL_TRIANGLE_STRIP, 12, 4);
        glDrawArrays(GL_TRIANGLE_STRIP, 16, 4);
        glDrawArrays(GL_TRIANGLE_STRIP, 20, 4);

        gbmSwapBuffers(&display, &surface);

        usleep(16000);
    }
}