- #include "esUtil.h"
-
- typedef struct
- {
- // Handle to a program object
- GLuint programObject;
-
- } UserData;
-
- ///
- // 加载着色器源代码,返回一个着色器的对象 GLuint
- //
- GLuint LoadShader ( GLenum type, const char *shaderSrc )
- {
- GLuint shader;
- GLint compiled;
-
- // 创建一个着色器对象
- shader = glCreateShader ( type );
-
- if ( shader == 0 )
- {
- return 0;
- }
-
- // 加载着色器源代码,并输出一个着色器对象:shader
- glShaderSource ( shader, 1, &shaderSrc, NULL );
-
- // 编译着色器
- glCompileShader ( shader );
-
- // 检查编译的状态,将结果输出给:compiled
- 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;
-
- }
-
- ///
- // Initialize the shader and program object
- //
- int Init ( ESContext *esContext )
- {
- UserData *userData = esContext->userData;
- //顶点着色器
- // vec4 vPosition : 声明一个输入属性数组
- // layout(location = 0) 限定符表示这个变量的位置是顶点属性0
- char vShaderStr[] =
- "#version 300 es \n"
- "layout(location = 0) in vec4 vPosition; \n"
- "void main() \n"
- "{ \n"
- " gl_Position = vPosition; \n"
- "} \n";
-
- //片元着色器
- //
- char fShaderStr[] =
- "#version 300 es \n"
- "precision mediump float; \n"
- "out vec4 fragColor; \n"
- "void main() \n"
- "{ \n"
- " fragColor = vec4 ( 0.2, 0.3, 0.7, 1.0 ); \n"
- "} \n";
-
- GLuint vertexShader;
- GLuint fragmentShader;
- GLuint programObject;
- GLint linked;
-
- // 创建顶点着色器对象
- vertexShader = LoadShader ( GL_VERTEX_SHADER, vShaderStr );
-
- // 创建片段着色器对象
- fragmentShader = LoadShader ( GL_FRAGMENT_SHADER, fShaderStr );
-
- // 创建一个空的程序对象,链接顶点着色器,片段着色器,不同的着色器源码编译成着色器对象后,他们必须连接到一个程序对象并一起链接,才能绘制图形
- programObject = glCreateProgram ( );
-
- if ( programObject == 0 )
- {
- return 0;
- }
-
- // 将着色器shader添加到program
- glAttachShader ( programObject, vertexShader );
- glAttachShader ( programObject, fragmentShader );
-
- // 把片元着色器和顶点着色器连接到程序对象, 创建可执行的 OpenGL ES program
- glLinkProgram ( programObject );
-
- // Check the link status
- glGetProgramiv ( programObject, GL_LINK_STATUS, &linked );
-
- if ( !linked )
- {
- GLint infoLen = 0;
-
- glGetProgramiv ( programObject, GL_INFO_LOG_LENGTH, &infoLen );
-
- if ( infoLen > 1 )
- {
- char *infoLog = malloc ( sizeof ( char ) * infoLen );
-
- glGetProgramInfoLog ( programObject, infoLen, NULL, infoLog );
- esLogMessage ( "Error linking program:\n%s\n", infoLog );
-
- free ( infoLog );
- }
-
- glDeleteProgram ( programObject );
- return FALSE;
- }
-
- // Store the program object
- userData->programObject = programObject;
-
- glClearColor ( 1.0f, 1.0f, 1.0f, 0.0f );
- return TRUE;
- }
-
- ///
- // Draw a triangle using the shader pair created in Init()
- //
- void Draw ( ESContext *esContext )
- {
- UserData *userData = esContext->userData;
- GLfloat vVertices[] = { -0.5f, 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 );
-
- // 每次绘制之前需要清除颜色缓冲区
- glClear ( GL_COLOR_BUFFER_BIT );
-
- // 绑定程序对象,进行渲染
- glUseProgram ( userData->programObject );
-
- //第一个参数指定我们要配置的顶点属性。和顶点着色器对应: layout(location = 0) in vec4 vPosition值(Location)吗?它可以把顶点属性的位置值设置为0。因为我们希望把数据传递到这一个顶点属性中,所以这里我们传入0。
- //第二个参数指定顶点属性的大小。顶点属性是一个vec3,它由3个值组成,所以大小是3。
- //第三个参数指定数据的类型,这里是GL_FLOAT(GLSL中vec*都是由浮点数值组成的)。
- glVertexAttribPointer ( 0, 3, GL_FLOAT, GL_FALSE, 0, vVertices );
- glEnableVertexAttribArray ( 0 );
-
- // 绘制图元
- glDrawArrays ( GL_TRIANGLES, 0, 3 );
- }
-
- void Shutdown ( ESContext *esContext )
- {
- UserData *userData = esContext->userData;
-
- glDeleteProgram ( userData->programObject );
- }
-
- int esMain ( ESContext *esContext )
- {
- esContext->userData = malloc ( sizeof ( UserData ) );
-
- esCreateWindow ( esContext, "Hello Triangle", 220, 240, ES_WINDOW_RGB );
-
- if ( !Init ( esContext ) )
- {
- return GL_FALSE;
- }
-
- esRegisterShutdownFunc ( esContext, Shutdown );
- esRegisterDrawFunc ( esContext, Draw );
-
- return GL_TRUE;
- }