我正在尝试扩展一个简单的Hello Triangle应用程序,使三角形围绕Y轴旋转。我尝试使用Android Hello Triangle作为参考,只需将代码调整为C ++并使用PowerVR SDK。到目前为止,我没有太多运气。三角形就在那里,静止。不确定是什么问题。这是我的初始化函数:
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;
}
这是Draw函数:
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);
}
所以基本上我在我的init中设置了View和Projection矩阵。然后,在Draw函数中,我使用旋转矩阵和新角度以规则的时间间隔重新计算模型矩阵。当角度达到360度时,我将其重置为0,冲洗,重复。
我检查了矩阵值,它们随着角度的变化而变化。所以当我将值传递给着色器时,我猜它正在崩溃。
答案 0 :(得分:1)
你可以在绘制循环结束时调用glGetError,并检查它是否始终为0?这通常是最好的起点。你的统一相关代码看起来很好(虽然我不知道PVRTMat4的细节,我现在假设它正在做它应该做的事情)。
我确实看到一个小错误,但我不确定它是否相关。
这:glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &linked);
应该是:glGetProgramiv(programObject, GL_LINK_STATUS, &linked);
您不希望将infolog长度检查为通过/失败条件,因为在链接成功的情况下,它不能保证为0。
=== EDIT ===
啊,我看到了问题。您只需清除Init
中的颜色缓冲区,您应该在Draw
每帧清除它。您的三角形可能正在旋转,但您无法看到它,因为它被原始三角形遮挡,而这个三角形从未被清除过。