//------------------------------------------------------------------------------
static void
drawCageVertices() {

    g_cageProgram.Use( );

    glUniformMatrix4fv(g_cageProgram.GetUniformModelViewProjectionMatrix(),
                       1, GL_FALSE, g_transformData.ModelViewProjectionMatrix);

    int numPoints = g_controlValues->GetNumVertices();
    std::vector<float> vbo;
    vbo.reserve(numPoints*6);

    float * positions = g_controlValues->BindCpuBuffer();

    float r, g, b;
    for (int i = 0; i < numPoints; ++i) {

        setSharpnessColor(g_coarseVertexSharpness[i], &r, &g, &b);

        vbo.push_back(positions[i*3+0]);
        vbo.push_back(positions[i*3+1]);
        vbo.push_back(positions[i*3+2]);
        vbo.push_back(r);
        vbo.push_back(g);
        vbo.push_back(b);
    }

    glBindVertexArray(g_cageVertexVAO);

    glBindBuffer(GL_ARRAY_BUFFER, g_cageVertexVBO);
    glBufferData(GL_ARRAY_BUFFER, (int)vbo.size() * sizeof(float), &vbo[0],
                 GL_STATIC_DRAW);

    g_cageProgram.EnableVertexAttributes();

    glPointSize(10.0f);
    glDrawArrays(GL_POINTS, 0, numPoints);
    glPointSize(1.0f);

    glBindVertexArray(0);
    glUseProgram(0);
}
//------------------------------------------------------------------------------
static void
drawCageEdges() {

    g_cageProgram.Use( );

    glUniformMatrix4fv(g_cageProgram.GetUniformModelViewProjectionMatrix(),
                       1, GL_FALSE, g_transformData.ModelViewProjectionMatrix);

    std::vector<float> vbo;
    vbo.reserve(g_coarseEdges.size() * 6);

    float * positions = g_controlValues->BindCpuBuffer();

    float r, g, b;
    for (int i = 0; i < (int)g_coarseEdges.size(); i+=2) {
        setSharpnessColor(g_coarseEdgeSharpness[i/2], &r, &g, &b);
        for (int j = 0; j < 2; ++j) {
            vbo.push_back(positions[g_coarseEdges[i+j]*3]);
            vbo.push_back(positions[g_coarseEdges[i+j]*3+1]);
            vbo.push_back(positions[g_coarseEdges[i+j]*3+2]);
            vbo.push_back(r);
            vbo.push_back(g);
            vbo.push_back(b);
        }
    }

    glBindVertexArray(g_cageEdgeVAO);

    glBindBuffer(GL_ARRAY_BUFFER, g_cageEdgeVBO);
    glBufferData(GL_ARRAY_BUFFER, (int)vbo.size() * sizeof(float), &vbo[0],
                 GL_STATIC_DRAW);

    g_cageProgram.EnableVertexAttributes();

    glDrawArrays(GL_LINES, 0, (int)g_coarseEdges.size());

    glBindVertexArray(0);
    glUseProgram(0);
}
//------------------------------------------------------------------------------
static void
drawStencils() {

    g_samplesProgram.Use( );

    glUniformMatrix4fv(g_cageProgram.GetUniformModelViewProjectionMatrix(),
                       1, GL_FALSE, g_transformData.ModelViewProjectionMatrix);

    glBindVertexArray(g_stencilsVAO);

    int numEdges = g_controlStencils->GetNumStencils() * 3;

    g_samplesProgram.EnableVertexAttributes();

    glBindBuffer(GL_ARRAY_BUFFER, g_stencilValues->BindVBO());

    g_samplesProgram.EnableVertexAttributes();

    glDrawArrays(GL_LINES, 0, numEdges*2);

    glBindVertexArray(0);
    glUseProgram(0);
}