【初始化Init】
// 初始化着色器和程序对象
int CTut2::Init( ESContext *esContext )
{
SUserData *userData = (SUserData*)esContext->userData;
// 顶点着色器定义一个输入attribute,后面的Draw函数将为每个顶点设置位置变量值
// 主函数声明开始执行,函数主体是复制输入vPosition到gl_Position输出变量中
// 每个顶点着色器必须输出位置值到gl_Position变量中,它将被传入到管线的下一个阶段
const char vertexShaderStr[] =
"attribute vec4 vPosition; \n"
"void main() \n"
"{ \n"
" gl_Position = vPosition; \n"
"} \n";
// 第一行宣布着色器默认的浮点变量精度
// gl_FragColor是片段着色器最终的输出值,这里输出的是红色
const char fragmentShaderStr[] =
"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;
// 加载顶点、片段着色器
vertexShader = LoadShader(GL_VERTEX_SHADER, vertexShaderStr);
fragmentShader = LoadShader(GL_FRAGMENT_SHADER, fragmentShaderStr);
// 一旦程序已经创建了顶点、片段着色器对象,需要去创建项目对象,项目是最终的链接对象
// 每个着色器在被绘制前都应联系到项目或项目对象
// 创建程序对象
programObject = glCreateProgram();
if (!programObject)
return 0;
glAttachShader(programObject, vertexShader);
glAttachShader(programObject, fragmentShader);
// 设置顶点着色器vPosition属性,绑定attribute 0
glBindAttribLocation(programObject, 0, "vPosition");
// 链接项目 检查错误
glLinkProgram(programObject);
glGetProgramiv(programObject, GL_LINK_STATUS, &linked);
if (!linked)
{
GLint infoLen = 0;
glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &infoLen);
if (infoLen > 1)
{
char *infoLog = new char[infoLen];
glGetProgramInfoLog(programObject, infoLen, NULL, infoLog);
esLogMessage("Error linking program:\n%s\n", infoLog);
delete infoLog;
}
glDeleteProgram(programObject);
return FALSE;
}
// 存储程序对象
userData->programObject = programObject;
// 设置清除颜色
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
return 1;
}
【加载着色器LoadShader】
GLuint LoadShader( GLenum type, const char *shaderSrc )
{
GLuint shader;
GLint compliled;
// 创建着色器对象
shader = glCreateShader(type);
if (!shader)
return 0;
// 加载着色器源
glShaderSource(shader, 1, &shaderSrc, NULL);
// 编译着色器
glCompileShader(shader);
// 测试编译状态
glGetShaderiv(shader, GL_COMPILE_STATUS, &compliled);
if (!compliled)
{
GLint infoLen = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
if (infoLen > 1)
{
char *infoLog = new char[infoLen];
glGetShaderInfoLog(shader, infoLen, NULL, infoLog);
esLogMessage("Error compliling shader:\n%s\n", infoLog);
delete infoLog;
}
glDeleteShader(shader);
return 0;
}
return shader;
}
【绘制Draw】
void CTut2::Draw( ESContext *esContext )
{
SUserData *userData = (SUserData*)esContext->userData;
GLfloat vVerts[] = { 0.0f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f};
// 设置视口
glViewport(0, 0, esContext->width, esContext->height);
// 清除颜色缓存
glClear(GL_COLOR_BUFFER_BIT);
// 使用程序对象
// 所有以后的渲染将使用附加的顶点着色器和片段着色器
glUseProgram((GLuint)userData->programObject);
// 加载顶点数据
// 每个顶点着色器中的属性都有一个唯一的无符号整数标识的位置
// 调用glVertexAttribPointer把数据装载到位置0
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVerts);
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLES, 0, 3);
// 系统一般双缓冲区,所有的渲染发生在后缓冲区,是屏幕上不可见的缓冲区内存
// 渲染完后交换前后缓冲区,即在下一帧时前缓冲区变成后缓冲区
eglSwapBuffers(esContext->eglDisplay, esContext->eglSurface);
}
【代码】
我这个是链接的OpenGL ES 2.0 Emulator v1.4的库,还用了《OpenGL ES 2.0 Programming Guide》书里的框架库,网上找得到的。
主要是方便学习opengles,而不是写框架……