I’m trying to extend a simple Hello Triangle application to have the triangle rotate around the Y axis. I tried using the Android Hello Triangle as a reference, just adapting the code to C++ and using the PowerVR SDK. So far, I’m not having much luck. The triangle just sits there, static. Not sure what the problem is. Here’s my init function:
int Init(ESContext* esContext)
{
UserData* userData = (UserData *)esContext->userData;
const char *vShaderStr =
"attribute vec4 vPosition; \n"
"uniform mat4 MVPMatrix;"
"void main() \n"
"{ \n"
" gl_Position = MVPMatrix * vPosition;\n"
"} \n";
const char *fShaderStr =
"precision mediump float; \n"
"void main() \n"
"{ \n"
" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); \n"
"} \n";
GLuint vertexShader;
GLuint fragmentShader;
GLuint programObject;
GLint linked;
GLfloat ratio = 320.0f/240.0f;
vertexShader = LoadShader(GL_VERTEX_SHADER, vShaderStr);
fragmentShader = LoadShader(GL_FRAGMENT_SHADER, fShaderStr);
programObject = glCreateProgram();
if (programObject == 0)
return 0;
glAttachShader(programObject, vertexShader);
glAttachShader(programObject, fragmentShader);
glBindAttribLocation(programObject, 0, "vPosition");
glLinkProgram(programObject);
glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &linked);
if (!linked)
{
GLint infoLen = 0;
glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &infoLen);
if (infoLen > 1)
{
char* infoLog = (char *)malloc(sizeof(char) * infoLen);
glGetProgramInfoLog(programObject, infoLen, NULL, infoLog);
free(infoLog);
}
glDeleteProgram(programObject);
return FALSE;
}
userData->programObject = programObject;
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glViewport(0, 0, esContext->width, esContext->height);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(userData->programObject);
userData->angle = 0.0f;
userData->start = time(NULL);
userData->ProjMatrix = PVRTMat4::Perspective(ratio*2.0f, 2.0f, 3.0f, 7.0f, PVRTMat4::eClipspace::OGL, false, false);
userData->ViewMatrix = PVRTMat4::LookAtLH(PVRTVec3(0.0f, 0.0f, -3.0f), PVRTVec3(0.0f, 0.0f, 0.0f), PVRTVec3(0.0f, 1.0f, 0.0f));
return TRUE;
}
Here’s the Draw function:
void Draw(ESContext *esContext)
{
GLfloat vVertices[] = {0.0f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f};
GLint MVPHandle;
PVRTMat4 MVPMatrix = PVRTMat4::Identity();
UserData* userData = (UserData *)esContext->userData;
if((GLint)(difftime(time(NULL), userData->start)) % 2 == 0)
{
if (userData->angle > 360.0f)
{
userData->angle = 0.0f;
}
else
{
userData->angle += 0.1f;
}
}
userData->ModelMatrix = PVRTMat4::RotationY(userData->angle);
MVPMatrix = userData->ViewMatrix * userData->ModelMatrix;
MVPMatrix = userData->ProjMatrix * MVPMatrix;
MVPHandle = glGetUniformLocation(userData->programObject, "MVPMatrix");
glUniformMatrix4fv(MVPHandle, 1, FALSE, MVPMatrix.ptr());
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices);
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLES, 0, 3);
eglSwapBuffers(esContext->eglDisplay, esContext->eglSurface);
}
So basically I’m setting up the View and Projection matrices in my init. Then, in the Draw function, I recalculate the Model matrix at regular timed intervals with a rotation matrix and the new angle. When the angle hits 360, I reset it to 0, rinse, repeat.
I checked the matrix values and they are changing as the angle changes. So I’m guessing it’s breaking down somewhere when it’s passing values to the shader.
Can you put a glGetError call at the end of the draw loop, and check that it is always 0? That’s usually the best place to start. Your uniform related code looks fine to me (although I don’t know the specifics of PVRTMat4, I’ll assume for now that it’s doing what it should).
I do see one small error, but I’m not sure if it’s related.
This:
glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &linked);Should be:
glGetProgramiv(programObject, GL_LINK_STATUS, &linked);You don’t want to check the infolog length as a pass/fail condition, as it’s not guaranteed to be 0 in the case of a successful link.
===EDIT===
Ah, I see the problem. You’re only clearing the color buffer in
Init, you should be clearing it inDrawevery frame. Your triangle is probably rotating, but you can’t see it because it’s obscured by the original triangle which is never cleared.