原地址: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. JSP页面中格式化日期为指顶格式

    有时候在页面中显示直接从数据库获取的日期时候会出现英文的日期格式.比如:

  2. [Leetcode Week1]Longest Substring Without Repeating Characters

    Longest Substring Without Repeating Characters题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/longes ...

  3. zlib库剖析(1):实现概览

    zlib库剖析(1):实现概览 http://blog.csdn.net/zhoudaxia/article/details/8034606 http://blog.chinaunix.net/uid ...

  4. css3 不常用但重要的属性

    IOS 2.-webkit-touch-callout (ios 2.0+) none:禁止弹出系统弹窗 default:默认 Android Common 1.-webkit-user-select ...

  5. 电脑IP总是变的问题

    如题,如何解决该问题? 右键---->个性化---->更改桌面图标---->添加网络图标 右键网络图标----->属性---->更改适配器设置---->右键属性,找 ...

  6. go语言中的json

    结构体类型转化为json格式 package main import ( "encoding/json" "fmt" ) //如果要转化成json格式,那么成员 ...

  7. elasticSearch script api

    Package org.elasticsearch.script Support for running user provided scripts (in the request, in clust ...

  8. selenium 警告框处理 (弹窗处理)

    在web应用中常常会遇见很多用JavaScript编写的alert .confirm 以及prompt 弹窗,这是就需要driver.switchTo().alert()来选取(定位)警告弹窗.再对弹 ...

  9. (二)shell变量

    (1)自定义变量 定义变量 变量名=变量值 变量名必须以字母或下划线开头,不能数字开头,区分大小写,ip=114.114.114.114 引用变量: $变量名 ${变量名} 查看变量: echo $变 ...

  10. 曼哈顿距离、欧几里得距离、闵氏距离(p→∞为切比雪夫距离)

    曼哈顿距离: 是由十九世纪的赫尔曼·闵可夫斯基所创词汇 ,是种使用在几何度量空间的几何学用语,用以标明两个点在标准坐标系上的绝对轴距总和. 曼哈顿距离——两点在南北方向上的距离加上在东西方向上的距离, ...