opengles3.0 (二)
创建简单的顶点和
char vShaderStr[] =
"#version 300 es \n"
"layout(location = 0) in vec4 vPosition; \n"
"void main() \n"
"{ \n"
" gl_Position = vPosition; \n"
"} \n";
这个顶点着色器声明一个输入属性的数组,一个名为vPosition的4分量向量。(每个顶点的位置(left,top,right,bottom))
layout(location = 0)是一个限定符,表示这个变量的位置是顶点属性0。
gl_Position = vPosition;他将vPosition输入属性拷贝到名为gl_Position的特殊输出。每个顶点做舍弃必须再gl_Positon变量中输出一个位置。定义传递到下一个阶段的位置。
片段着色器:
char fShaderStr[] =
"#version 300 es \n"
"precision mediump float; \n"
"out vec4 fragColor; \n"
"void main() \n"
"{ \n"
" fragColor = vec4 ( 1.0, 0.0, 0.0, 1.0 ); \n"
"}
片段着色器声明一个输出变量fragColor,这是一个4分量的向量。写入这个变量的值将被输出到颜色缓冲区,,这个例子,所有片段的着色器输出都是红色(1.0.0.0.0.0,1.0)
编译和加载着色器:
GLuint LoadShader ( GLenum type, const char *shaderSrc )
{
GLuint shader;
GLint compiled;
// Create the shader object
shader = glCreateShader ( type );
if ( shader == 0 )
{
return 0;
}
// Load the shader source
glShaderSource ( shader, 1, &shaderSrc, NULL );
// Compile the shader
glCompileShader ( shader );
// Check the compile status
glGetShaderiv ( shader, GL_COMPILE_STATUS, &compiled );
if ( !compiled )
{
GLint infoLen = 0;
glGetShaderiv ( shader, GL_INFO_LOG_LENGTH, &infoLen );
if ( infoLen > 1 )
{
char *infoLog = malloc ( sizeof ( char ) * infoLen );
glGetShaderInfoLog ( shader, infoLen, NULL, infoLog );
esLogMessage ( "Error compiling shader:\n%s\n", infoLog );
free ( infoLog );
}
glDeleteShader ( shader );
return 0;
}
return shader;
}
glCreateShader:创建指定类型的着色器。type:顶点片段。
glShaderSource:加载到着色器对象
glCompileShader:编译着色器
glGetShaderiv:返回编译的状态
创建一个程序对象,并链接着色器。
GLuint vertexShader;
GLuint fragmentShader;
GLuint programObject;
GLint linked;
// Load the vertex/fragment shaders
vertexShader = LoadShader ( GL_VERTEX_SHADER, vShaderStr );
fragmentShader = LoadShader ( GL_FRAGMENT_SHADER, fShaderStr );
// Create the program object
programObject = glCreateProgram ( );
if ( programObject == 0 )
{
return 0;
}
glAttachShader ( programObject, vertexShader );
glAttachShader ( programObject, fragmentShader );
// Link the program
glLinkProgram ( programObject );
// Check the link status
glGetProgramiv ( programObject, GL_LINK_STATUS, &linked );
一旦应用程序为顶点和片段着色器创建爱你了着色器对象,就需要创建一个程序对象。从概念上说,程序对象可以视为最总链接的程序。不同的着色器比编译为一个着色器对象之后,他们必须链接到一个程序对象并一起链接,才能绘制图形。
glUseProgram(programObject);
用程序对象句柄调用glUseProgram之后,所有后续的渲染将用链接到程序对象的顶点和片段着色器进行
绘制视口和清除颜色缓冲区:
// Set the viewport
glViewport ( 0, 0, esContext->width, esContext->height );
//通知OPENGES用于绘制的2D渲染表面的原点、宽度、高度定义。x,y是原点坐标
// Clear the color buffer
glClear ( GL_COLOR_BUFFER_BIT );
加载几何形状和绘制图元:
清除颜色缓冲区、设置视口、和加载程序对象之后,必须指定三角形的几何形状。三角形的顶点由vVertices数组中的3个坐标(X,Y,Z)指定。
GLfloat vVertices[] = { 0.0f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f
};
// Set the viewport
glViewport ( 0, 0, esContext->width, esContext->height );
// Clear the color buffer
glClear ( GL_COLOR_BUFFER_BIT );
// Use the program object
glUseProgram ( userData->programObject );
// Load the vertex data
glVertexAttribPointer ( 0, 3, GL_FLOAT, GL_FALSE, 0, vVertices );
glEnableVertexAttribArray ( 0 );
glDrawArrays ( GL_TRIANGLES, 0, 3 );
顶点位置需要加载到GL,并链接到顶点着色器中声明的vPosition属性。
glDrawArrays函数实现这个目的,这个函数的绘制三角形,直线,或者带条状的图元。
显示后台缓冲区:
eglSwapBuffers