static void CheckGLError(const char* printMsg)
{
for (GLint error = glGetError(); error; error = glGetError())
{
ALog_E("after %s() glError (0x%x)", printMsg, error);
}
}
/**
* Compile a shader
* shaderType is GL_VERTEX_SHADER or GL_FRAGMENT_SHADER
*/
static GLuint LoadShader(GLenum shaderType, const char* shaderSource)
{
// Create the shader object
GLuint shader = glCreateShader(shaderType);
if (shader == 0)
{
CheckGLError("glCreateShader");
return shader;
}
// Load the shader source
glShaderSource(shader, 1, &shaderSource, NULL);
// Compile the shader
glCompileShader(shader);
GLint compiled;
// Check the compile status
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
if (!compiled)
{
GLint infoLen;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
if (infoLen != 0)
{
char buf[infoLen];
glGetShaderInfoLog(shader, infoLen, NULL, buf);
ALog_E("Could not compile shader %d:%s", shaderType, buf);
glDeleteShader(shader);
return 0;
}
}
return shader;
}
/**
* Load vertex and fragment shader, create a program object, link program
*/
static GLuint LoadProgram(const char* vertexSource, const char* fragmentSource)
{
GLuint program;
// Load the vertex shaders
GLuint vertexShader = LoadShader(GL_VERTEX_SHADER, vertexSource);
if (vertexShader == 0)
{
return 0;
}
// Load the fragment shaders
GLuint fragmentShader = LoadShader(GL_FRAGMENT_SHADER, fragmentSource);
if (fragmentShader == 0)
{
return 0;
}
// Create the program object
program = glCreateProgram();
if (program == 0)
{
CheckGLError("glCreateProgram");
return 0;
}
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
// Link the program
glLinkProgram(program);
GLint linkStatus;
// Check the link status
glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
if (!linkStatus)
{
GLint bufLength;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
if (bufLength != 0)
{
char buf[bufLength];
glGetProgramInfoLog(program, bufLength, NULL, buf);
ALog_E("Could not link program: %s", buf);
}
glDeleteProgram(program);
return 0;
}
// Free up no longer needed shader resources
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
return program;
}
可以载入顶点和片段shader,并编译附加到Program上,最后返回链接后的Program, 开箱即用,支持错误输出。