原地址:http://blog.csdn.net/myarrow/article/details/7707943

1. 保存全局变量的数据结构

以下例子程序均基于Linux平台。

  1. typedef struct _escontext
  2. {
  3. void*       userData;                    // Put your user data here...
  4. GLint       width;                          // Window width
  5. GLint       height;                         // Window height
  6. EGLNativeWindowType  hWnd;  // Window handle
  7. EGLDisplay  eglDisplay;             // EGL display
  8. EGLContext  eglContext;            // EGL context
  9. EGLSurface  eglSurface;            // EGL surface
  10. // Callbacks
  11. void (ESCALLBACK *drawFunc) ( struct _escontext * );
  12. void (ESCALLBACK *keyFunc) ( struct _escontext *, unsigned char, int, int );
  13. void (ESCALLBACK *updateFunc) ( struct _escontext *, float deltaTime );
  14. }ESContext;
  1. typedef struct
  2. {
  3. // Handle to a program object
  4. GLuint programObject;
  5. // Atrribute Location
  6. GLint positionLoc;
  7. GLint textureLoc;
  8. // Uniform location
  9. GLint matrixModeLoc;
  10. GLint matrixViewLoc;
  11. GLint matrixPerspectiveLoc;
  12. // Sampler location
  13. GLint samplerLoc;
  14. // texture
  15. GLuint texture;
  16. } UserData;

2. 初始化EGL渲染环境和相关元素(第一步曲)

  1. int InitEGL(ESContext * esContext)
  2. {
  3. NativeWindowType eglWindow = NULL;
  4. EGLDisplay display;
  5. EGLContext context;
  6. EGLSurface surface;
  7. EGLConfig configs[2];
  8. EGLBoolean eRetStatus;
  9. EGLint majorVer, minorVer;
  10. EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
  11. EGLint numConfigs;
  12. EGLint cfg_attribs[] = {EGL_BUFFER_SIZE,    EGL_DONT_CARE,
  13. EGL_DEPTH_SIZE,     16,
  14. EGL_RED_SIZE,       5,
  15. EGL_GREEN_SIZE,     6,
  16. EGL_BLUE_SIZE,      5,
  17. EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
  18. EGL_NONE};
  19. // Get default display connection
  20. display = eglGetDisplay((EGLNativeDisplayType)EGL_DEFAULT_DISPLAY);
  21. if ( display == EGL_NO_DISPLAY )
  22. {
  23. return EGL_FALSE;
  24. }
  25. // Initialize EGL display connection
  26. eRetStatus = eglInitialize(display, &majorVer, &minorVer);
  27. if( eRetStatus != EGL_TRUE )
  28. {
  29. return EGL_FALSE;
  30. }
  31. //Get a list of all EGL frame buffer configurations for a display
  32. eRetStatus = eglGetConfigs (display, configs, 2, &numConfigs);
  33. if( eRetStatus != EGL_TRUE )
  34. {
  35. return EGL_FALSE;
  36. }
  37. // Get a list of EGL frame buffer configurations that match specified attributes
  38. eRetStatus = eglChooseConfig (display, cfg_attribs, configs, 2, &numConfigs);
  39. if( eRetStatus != EGL_TRUE  || !numConfigs)
  40. {
  41. return EGL_FALSE;
  42. }
  43. // Create a new EGL window surface
  44. surface = eglCreateWindowSurface(display, configs[0], eglWindow, NULL);
  45. if (surface == EGL_NO_SURFACE)
  46. {
  47. return EGL_FALSE;
  48. }
  49. // Set the current rendering API (EGL_OPENGL_API, EGL_OPENGL_ES_API,EGL_OPENVG_API)
  50. eRetStatus = eglBindAPI(EGL_OPENGL_ES_API);
  51. if (eRetStatus != EGL_TRUE)
  52. {
  53. return EGL_FALSE;
  54. }
  55. // Create a new EGL rendering context
  56. context = eglCreateContext (display, configs[0], EGL_NO_CONTEXT, context_attribs);
  57. if (context == EGL_NO_CONTEXT)
  58. {
  59. return EGL_FALSE;
  60. }
  61. // Attach an EGL rendering context to EGL surfaces
  62. eRetStatus = eglMakeCurrent (display, surface, surface, context);
  63. if( eRetStatus != EGL_TRUE )
  64. {
  65. return EGL_FALSE;
  66. }
  67. //If interval is set to a value of 0, buffer swaps are not synchronized to a video frame, and the swap happens as soon as the render is complete.
  68. eglSwapInterval(display,0);
  69. // Return the context elements
  70. esContext->eglDisplay = display;
  71. esContext->eglSurface = surface;
  72. esContext->eglContext = context;
  73. return EGL_TRUE;
  74. }

3. 生成Program (第二步曲)

3.1 LoadShader

LoadShader主要实现以下功能:

1) 创建Shader对象

2) 装载Shader源码

3) 编译Shader

其实现参考代码如下:

  1. /* type specifies the Shader type: GL_VERTEX_SHADER or GL_FRAGMENT_SHADER */
  2. GLuint LoadShader ( GLenum type, const char *shaderSrc )
  3. {
  4. GLuint shader;
  5. GLint compiled;
  6. // Create an empty shader object, which maintain the source code strings that define a shader
  7. shader = glCreateShader ( type );
  8. if ( shader == 0 )
  9. return 0;
  10. // Replaces the source code in a shader object
  11. glShaderSource ( shader, 1, &shaderSrc, NULL );
  12. // Compile the shader object
  13. glCompileShader ( shader );
  14. // Check the shader object compile status
  15. glGetShaderiv ( shader, GL_COMPILE_STATUS, &compiled );
  16. if ( !compiled )
  17. {
  18. GLint infoLen = 0;
  19. glGetShaderiv ( shader, GL_INFO_LOG_LENGTH, &infoLen );
  20. if ( infoLen > 1 )
  21. {
  22. char* infoLog = malloc (sizeof(char) * infoLen );
  23. glGetShaderInfoLog ( shader, infoLen, NULL, infoLog );
  24. esLogMessage ( "Error compiling shader:\n%s\n", infoLog );
  25. free ( infoLog );
  26. }
  27. glDeleteShader ( shader );
  28. return 0;
  29. }
  30. return shader;
  31. }

1)glCreateShader 
       它创建一个空的shader对象,它用于维护用来定义shader的源码字符串。支持以下两种shader:
      (1) GL_VERTEX_SHADER: 它运行在可编程的“顶点处理器”上,用于代替固定功能的顶点处理;
      ( 2) GL_FRAGMENT_SHADER: 它运行在可编程的“片断处理器”上,用于代替固定功能的片段处理;

2)glShaderSource
        shader对象中原来的源码全部被新的源码所代替。

3)glCompileShader
       编译存储在shader对象中的源码字符串,编译结果被当作shader对象状态的一部分被保存起来,可通过glGetShaderiv函数获取编译状态。

4)glGetShaderiv
       获取shader对象参数,参数包括:GL_SHADER_TYPE, GL_DELETE_STATUS, GL_COMPILE_STATUS, GL_INFO_LOG_LENGTH, GL_SHADER_SOURCE_LENGTH.

3.2 LoadProgram

其参考代码如下:

  1. GLuint LoadProgram ( const char *vShaderStr, const char *fShaderStr )
  2. {
  3. GLuint vertexShader;
  4. GLuint fragmentShader;
  5. GLuint programObject;
  6. GLint linked;
  7. // Load the vertex/fragment shaders
  8. vertexShader = LoadShader ( GL_VERTEX_SHADER, vShaderStr );
  9. fragmentShader = LoadShader ( GL_FRAGMENT_SHADER, fShaderStr );
  10. // Create the program object
  11. programObject = glCreateProgram ( );
  12. if ( programObject == 0 )
  13. return 0;
  14. // Attaches a shader object to a program object
  15. glAttachShader ( programObject, vertexShader );
  16. glAttachShader ( programObject, fragmentShader );
  17. // Bind vPosition to attribute 0
  18. glBindAttribLocation ( programObject, 0, "vPosition" );
  19. // Link the program object
  20. glLinkProgram ( programObject );
  21. // Check the link status
  22. glGetProgramiv ( programObject, GL_LINK_STATUS, &linked );
  23. if ( !linked )
  24. {
  25. GLint infoLen = 0;
  26. glGetProgramiv ( programObject, GL_INFO_LOG_LENGTH, &infoLen );
  27. if ( infoLen > 1 )
  28. {
  29. char* infoLog = malloc (sizeof(char) * infoLen );
  30. glGetProgramInfoLog ( programObject, infoLen, NULL, infoLog );
  31. esLogMessage ( "Error linking program:\n%s\n", infoLog );
  32. free ( infoLog );
  33. }
  34. glDeleteProgram ( programObject );
  35. return GL_FALSE;
  36. }
  37. // Free no longer needed shader resources
  38. glDeleteShader ( vertexShader );
  39. glDeleteShader ( fragmentShader );
  40. return programObject;
  41. }

1)glCreateProgram
      建立一个空的program对象,shader对象可以被连接到program对像
2)glAttachShader
      program对象提供了把需要做的事连接在一起的机制。在一个program中,在shader对象被连接在一起之前,必须先把shader连接到program上。
3)glBindAttribLocation 
       把program的顶点属性索引与顶点shader中的变量名进行绑定。
4)glLinkProgram
       连接程序对象。如果任何类型为GL_VERTEX_SHADER的shader对象连接到program,它将产生在“可编程顶点处理器”上可执行的程序;如果任何类型为GL_FRAGMENT_SHADER的shader对象连接到program,它将产生在“可编程片断处理器”上可执行的程序。
5)glGetProgramiv
       获取program对象的参数值,参数有:GL_DELETE_STATUS, GL_LINK_STATUS, GL_VALIDATE_STATUS, GL_INFO_LOG_LENGTH, GL_ATTACHED_SHADERS, GL_ACTIVE_ATTRIBUTES, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, GL_ACTIVE_UNIFORMS, GL_ACTIVE_UNIFORM_MAX_LENGTH.

3.3 CreateProgram

在3.1中只实现了Shader的编译,在3.2中只实现了Program的链接,现在还缺少真正供进行编译和链接的源码,其参考代码如下:

  1. int CreateProgram(ESContext * esContext)
  2. {
  3. GLuint programObject;
  4. GLbyte vShaderStr[] =
  5. "attribute vec4 vPosition;    \n"
  6. "void main()                  \n"
  7. "{                            \n"
  8. "   gl_Position = vPosition;  \n"
  9. "}                            \n";
  10. GLbyte fShaderStr[] =
  11. "precision mediump float;\n"\
  12. "void main()                                  \n"
  13. "{                                            \n"
  14. "  gl_FragColor = vec4 ( 1.0, 0.0, 0.0, 1.0 );\n"
  15. "}                                                    \n";
  16. // Create user data
  17. esContext->userData = malloc(sizeof(UserData));
  18. UserData *userData = esContext->userData;
  19. // Load the shaders and get a linked program object
  20. programObject = LoadProgram ( (const char*)vShaderStr, (const char*)fShaderStr );
  21. if(programObject == 0)
  22. {
  23. return GL_FALSE;
  24. }
  25. // Store the program object
  26. userData->programObject = programObject;
  27. // Get the attribute locations
  28. userData->positionLoc = glGetAttribLocation ( g_programObject, "v_position" );
  29. glClearColor ( 0.0f, 0.0f, 0.0f, 1.0f );
  30. return 0;
  31. }

4. 安装并执行Program(第三步)

  1. void Render ( ESContext *esContext )
  2. {
  3. UserData *userData = esContext->userData;
  4. GLfloat vVertices[] = {  0.0f,  0.5f, 0.0f,
  5. -0.5f, -0.5f, 0.0f,
  6. 0.5f, -0.5f, 0.0f };
  7. // Set the viewport
  8. glViewport ( 0, 0, esContext->width, esContext->height );
  9. // Clear the color buffer
  10. glClear ( GL_COLOR_BUFFER_BIT );
  11. // Use the program object
  12. glUseProgram ( userData->programObject );
  13. // Load the vertex data
  14. glVertexAttribPointer ( 0, 3, GL_FLOAT, GL_FALSE, 0, vVertices );
  15. glEnableVertexAttribArray ( 0 );
  16. glDrawArrays ( GL_TRIANGLES, 0, 3 );
  17. eglSwapBuffers(esContext->eglDisplay, esContext->eglSurface);
  1. }

4.1 glClear

清除指定的buffer到预设值。可清除以下四类buffer:

1)GL_COLOR_BUFFER_BIT

2)GL_DEPTH_BUFFER_BIT

3)GL_ACCUM_BUFFER_BIT

4)GL_STENCIL_BUFFER_BIT

预设值通过glClearColor, glClearIndex, glClearDepth, glClearStencil, 和glClearAccum来设置。

1)gClearColor

指定color buffer的清除值,当调用glClear(GL_COLOR_BUFFER_BIT)时才真正用设定的颜色值清除color buffer。参数值的范围为:0~1。

void glClearColor( GLclampf   red, GLclampf   green,  GLclampf   blue,  GLclampf   alpha);

2)glClearIndex

指定color index buffer清除值。void glClearIndex( GLfloat   c);

3)glClearDepth

指定depth buffer的清除值,取值范围为:0~1,默认值为1。

void glClearDepth( GLclampd   depth);

4)glClearStencil

指定stencil buffer清除值的索引,初始值为0。void glClearStencil( GLint   s);

5)glClearAccum

指定accumulation buffer的清除值,初始值为0,取值范围为:-1~1

void glClearAccum( GLfloat red,GLfloat green,GLfloat blue,GLfloat alpha);

4.2 glUseProgram

安装一个program object,并把它作为当前rendering state的一部分。

     1) 当一个可执行程序被安装到vertex processor,下列OpenGL固定功能将被disable:

  • The modelview matrix is not applied to vertex coordinates.
  • The projection matrix is not applied to vertex coordinates.
  • The texture matrices are not applied to texture coordinates.
  • Normals are not transformed to eye coordinates.
  • Normals are not rescaled or normalized.
  • Normalization of GL_AUTO_NORMAL evaluated normals is not performed.
  • Texture coordinates are not generated automatically.
  • Per-vertex lighting is not performed.
  • Color material computations are not performed.
  • Color index lighting is not performed.
  • This list also applies when setting the current raster position.

2) 当一个可执行程序被安装到fragment processor,下列OpenGL固定功能将被disable:

  • Texture environment and texture functions are not applied.
  • Texture application is not applied.
  • Color sum is not applied.
  • Fog is not applied.

4.3 glVertexAttribPointer

定义一个通用顶点属性数组。当渲染时,它指定了通用顶点属性数组从索引index处开始的位置数据格式。其定义如下:

  1. void glVertexAttribPointer(
  2. GLuint   index,           // 指示将被修改的通用顶点属性的索引
  3. GLint   size,             // 指点每个顶点元素个数(1~4)
  4. GLenum   type,            // 数组中每个元素的数据类型
  5. GLboolean   normalized,   //指示定点数据值是否被归一化(归一化<[-1,1]或[0,1]>:GL_TRUE,直接使用:GL_FALSE)
  6. GLsizei   stride,         // 连续顶点属性间的偏移量,如果为0,相邻顶点属性间紧紧相邻
  7. const GLvoid *   pointer);//顶点数组
  8. :其index应该小于#define GL_MAX_VERTEX_ATTRIBS               0x8869

4.4 glEnableVertexAttribArray

Enable由索引index指定的通用顶点属性数组。

void glEnableVertexAttribArray( GLuint   index);
      void glDisableVertexAttribArray( GLuint   index);

默认状态下,所有客户端的能力被disabled,包括所有通用顶点属性数组。如果被Enable,通用顶点属性数组中的值将被访问并被用于rendering,通过调用顶点数组命令:glDrawArrays, glDrawElements, glDrawRangeElements, glArrayElement, glMultiDrawElements, or glMultiDrawArrays.

4.5 glDrawArrays

void glDrawArrays( GLenum   mode,  
                                  GLint   first,  
                                  GLsizei   count);

1) mode:指明render原语,如:GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_TRIANGLES, GL_QUAD_STRIP, GL_QUADS, 和 GL_POLYGON。

2) first: 指明Enable数组中起始索引。

3) count: 指明被render的原语个数。

可以预先使用单独的数据定义vertex、normal和color,然后通过一个简单的glDrawArrays构造一系列原语。当调用glDrawArrays时,它使用每个enable的数组中的count个连续的元素,来构造一系列几何原语,从第first个元素开始。

4.6 eglSwapBuffers

把EGL surface中的color buffer提交到native window进行显示。

EGLBoolean eglSwapBuffers(EGLDisplay display,EGLSurface surface)

5. 协调组织

在前面的描述中,三步曲已经完成了:

1)初始化EGL环境,为绘图做好准备

2)生成Program

3)安装并执行Program

只有这三个关键人物,还不能运行,还需要一个协调组织者。其参考代码如下:

  1. int main(int argc, char** argv)
  2. {
  3. ESContext esContext;
  4. UserData  userData;
  5. int iFrames;
  6. unsigned long iStartTime,iEndTime;
  7. int iDeltaTime;
  8. memset( &esContext, 0, sizeof( ESContext) );
  9. esContext.userData = &userData;
  10. esContext.width = 1280;
  11. esContext.height = 720;
  12. // Init EGL display, surface and context
  13. if(!InitEGL(&esContext))
  14. {
  15. printf("Init EGL fail\n");
  16. return GL_FALSE;
  17. }
  18. // compile shader, link program
  19. if(!CreateProgram(&esContext))
  20. {
  21. printf("Create Program fail\n");
  22. return GL_FALSE;
  23. }
  24. iStartTime = GetCurTime();
  25. iFrames = 0;
  26. while(1)
  27. {    // render a frame
  28. Render(&esContext);
  29. iFrames++;
  30. iEndTime = GetCurTime();
  31. iDeltaTime  = iEndTime - iStartTime;
  32. if(iDeltaTime >= 5000)
  33. {
  34. iStartTime = iEndTime;
  35. float fFrame = iFrames * 1000.0 / iDeltaTime;
  36. iFrames = 0;
  37. printf("Frame: %f\n", fFrame);
  38. }
  39. }
  40. glDeleteProgram (esContext.userData->programObject);
  41. return GL_TRUE;
  42. }

OpenGL ES2.0编程三步曲 -转的更多相关文章

  1. iOS开发——图形编程OC篇&OpenGL ES2.0编程步骤

    OpenGL ES2.0编程步骤 OpenGL ES (OpenGL for Embedded Systems) 是 OpenGL 三维图形 API 的子集,针对手机.PDA和游戏主机等嵌入式设备而设 ...

  2. STM32中断编程三步曲教你弄会中断设置以及中断优先级设置

    中断作为stm32中必不可少的一个功能,其重要性是不言而喻的因此把中断学习好是根本. 所以今天就来好好啃一下中断配置的知识,俗话说:磨刀不误砍柴工.问题是什么呢?项目中我用到了一个触摸键盘TTP229 ...

  3. OpenGL ES2.0 基本编程

    1. EGL OpenGL ES命令须要一个rendering context和一个drawing surface. Rendering Context: 保存当前的OpenGL ES状态. Draw ...

  4. OpenGL ES2.0 入门经典例子

    原文链接地址:http://www.raywenderlich.com/3664/opengl-es-2-0-for-iphone-tutorial 免责申明(必读!):本博客提供的所有教程的翻译原稿 ...

  5. OpenGL ES2.0入门详解

    引自:http://blog.csdn.net/wangyuchun_799/article/details/7736928  1.决定你要支持的OpenGL ES的版本.目前,OpenGL ES包含 ...

  6. VC控件自绘制三步曲

    http://blog.csdn.net/lijie45655/article/details/6362441 实现自定义绘制的三步曲 既然您已经了解了绘制控件可用的各种选项(包括使用自定义绘制的好处 ...

  7. Membership三步曲之进阶篇 - 深入剖析Provider Model

    Membership 三步曲之进阶篇 - 深入剖析Provider Model 本文的目标是让每一个人都知道Provider Model 是什么,并且能灵活的在自己的项目中使用它. Membershi ...

  8. Membership三步曲之入门篇 - Membership基础示例

    Membership 三步曲之入门篇 - Membership基础示例 Membership三步曲之入门篇 -  Membership基础示例 Membership三步曲之进阶篇 -  深入剖析Pro ...

  9. [转]Membership三步曲之入门篇 - Membership基础示例

    本文转自:http://www.cnblogs.com/jesse2013/p/membership.html Membership三步曲之入门篇 - Membership基础示例   Members ...

随机推荐

  1. JVM 性能排查--查看哪个对象占用内存大

    参考:http://blog.csdn.net/chenleixing/article/details/44227327/ 1.  在IE地址栏中输入:http://localhost/test/in ...

  2. 【洛谷 P1631】 序列合并 (堆)

    题目链接 直接暴力搞是\(n\)方的复杂度.\(n^2\)个数选\(n\)个最小的,容易想到堆. 我们堆里记录两个信息:到\(A\)数组哪个位置了,到\(B\)数组哪个位置了, 我直接把这两个信息存在 ...

  3. centos6.4 nginx+mysql+php整合phpmyadmin出错解决方案

    今天在centos下整合phpmyadmin出错,错误提示如下: Error during session start; please check your PHP and/or webserver ...

  4. 之江学院第0届校赛 qwb去面试 (找规律)

    Description 某一天,qwb去WCfun面试,面试官问了他一个问题:把一个正整数n拆分成若干个正整数的和,请求出这些数乘积的最大值. qwb比较猥琐,借故上厕所偷偷上网求助,聪明的你能帮助他 ...

  5. PHP性能追踪及分析工具xhprof的安装与使用

    对于本地开发环境来说,进行性能分析xdebug是够用了,但如果是线上环境的话,xdebug消耗较大,配置也不够灵活,因此线上环境建议使用xhprof进行PHP性能追踪及分析. 我们今天就简单介绍一下x ...

  6. HDU1143(3*N的地板铺1*2的砖)

    Tri Tiling Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  7. RabbitMQ消息队列(二): 工作队列

    1. 工作队列: 对于资源密集型任务,我们等待其处理完成在很多情况下是不现实的,比如无法在http的短暂请求窗口中处理大量耗时任务, 为了达到主线程无需等待,任务异步执行的要求,我们可以将任务加入任务 ...

  8. python的上下文管理(context)(1)

    本文转载自:http://blog.csdn.net/G_66_hero/article/details/53048540 什么是Python中的上下文管理器 怎么使用上下文管理器 如何创建自己的上下 ...

  9. 计蒜客 1460.Ryuji doesn't want to study-树状数组 or 线段树 (ACM-ICPC 2018 徐州赛区网络预赛 H)

    H.Ryuji doesn't want to study 27.34% 1000ms 262144K   Ryuji is not a good student, and he doesn't wa ...

  10. 超级素数(sprime) (BFS)

    问题 G: 超级素数(sprime) 时间限制: 1 Sec  内存限制: 64 MB提交: 47  解决: 11[提交][状态][讨论版] 题目描述 超级素数是指一个素数,每去掉后面一个数字,总能保 ...