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, ¤tTime);
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);
}
}