zoukankan      html  css  js  c++  java
  • OpenGL ES2.0编程三步曲 -转

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

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

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

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    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.   
    11.    // Callbacks  
    12.    void (ESCALLBACK *drawFunc) ( struct _escontext * );  
    13.    void (ESCALLBACK *keyFunc) ( struct _escontext *, unsigned charintint );  
    14.    void (ESCALLBACK *updateFunc) ( struct _escontext *, float deltaTime );  
    15. }ESContext;  
    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. typedef struct  
    2. {  
    3.    // Handle to a program object  
    4.    GLuint programObject;  
    5.   
    6.    // Atrribute Location  
    7.    GLint positionLoc;  
    8.    GLint textureLoc;  
    9.   
    10.    // Uniform location  
    11.    GLint matrixModeLoc;  
    12.    GLint matrixViewLoc;  
    13.    GLint matrixPerspectiveLoc;  
    14.   
    15.    // Sampler location  
    16.    GLint samplerLoc;  
    17.   
    18.    // texture  
    19.    GLuint texture;  
    20. } UserData;  



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

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. int InitEGL(ESContext * esContext)  
    2. {  
    3.      NativeWindowType eglWindow = NULL;  
    4.   
    5.      EGLDisplay display;  
    6.      EGLContext context;  
    7.      EGLSurface surface;  
    8.   
    9.      EGLConfig configs[2];  
    10.      EGLBoolean eRetStatus;  
    11.      EGLint majorVer, minorVer;  
    12.      EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};  
    13.   
    14.      EGLint numConfigs;  
    15.      EGLint cfg_attribs[] = {EGL_BUFFER_SIZE,    EGL_DONT_CARE,  
    16.                              EGL_DEPTH_SIZE,     16,  
    17.                              EGL_RED_SIZE,       5,  
    18.                              EGL_GREEN_SIZE,     6,  
    19.                              EGL_BLUE_SIZE,      5,  
    20.                              EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,  
    21.                              EGL_NONE};  
    22.   
    23.      // Get default display connection   
    24.      display = eglGetDisplay((EGLNativeDisplayType)EGL_DEFAULT_DISPLAY);  
    25.      if ( display == EGL_NO_DISPLAY )  
    26.      {  
    27.           return EGL_FALSE;  
    28.      }  
    29.   
    30.      // Initialize EGL display connection  
    31.      eRetStatus = eglInitialize(display, &majorVer, &minorVer);  
    32.      if( eRetStatus != EGL_TRUE )  
    33.      {  
    34.           return EGL_FALSE;  
    35.      }  
    36.   
    37.      //Get a list of all EGL frame buffer configurations for a display  
    38.      eRetStatus = eglGetConfigs (display, configs, 2, &numConfigs);  
    39.      if( eRetStatus != EGL_TRUE )  
    40.      {  
    41.           return EGL_FALSE;  
    42.      }  
    43.   
    44.      // Get a list of EGL frame buffer configurations that match specified attributes  
    45.      eRetStatus = eglChooseConfig (display, cfg_attribs, configs, 2, &numConfigs);  
    46.      if( eRetStatus != EGL_TRUE  || !numConfigs)  
    47.      {  
    48.           return EGL_FALSE;  
    49.      }  
    50.   
    51.      // Create a new EGL window surface  
    52.      surface = eglCreateWindowSurface(display, configs[0], eglWindow, NULL);  
    53.      if (surface == EGL_NO_SURFACE)  
    54.      {  
    55.           return EGL_FALSE;  
    56.      }  
    57.   
    58.      // Set the current rendering API (EGL_OPENGL_API, EGL_OPENGL_ES_API,EGL_OPENVG_API)  
    59.      eRetStatus = eglBindAPI(EGL_OPENGL_ES_API);  
    60.      if (eRetStatus != EGL_TRUE)  
    61.      {  
    62.           return EGL_FALSE;  
    63.      }  
    64.   
    65.      // Create a new EGL rendering context  
    66.      context = eglCreateContext (display, configs[0], EGL_NO_CONTEXT, context_attribs);  
    67.      if (context == EGL_NO_CONTEXT)  
    68.      {  
    69.           return EGL_FALSE;  
    70.      }  
    71.   
    72.      // Attach an EGL rendering context to EGL surfaces  
    73.      eRetStatus = eglMakeCurrent (display, surface, surface, context);  
    74.      if( eRetStatus != EGL_TRUE )  
    75.      {  
    76.           return EGL_FALSE;  
    77.      }  
    78.      //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.  
    79.      eglSwapInterval(display,0);  
    80.   
    81.      // Return the context elements  
    82.      esContext->eglDisplay = display;  
    83.      esContext->eglSurface = surface;  
    84.      esContext->eglContext = context;  
    85.   
    86.      return EGL_TRUE;  
    87. }  


    3. 生成Program (第二步曲)

    3.1 LoadShader

    LoadShader主要实现以下功能:

           1) 创建Shader对象

           2) 装载Shader源码

           3) 编译Shader

          其实现参考代码如下:

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    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.      
    7.    // Create an empty shader object, which maintain the source code strings that define a shader  
    8.    shader = glCreateShader ( type );  
    9.   
    10.    if ( shader == 0 )  
    11.     return 0;  
    12.   
    13.    // Replaces the source code in a shader object  
    14.    glShaderSource ( shader, 1, &shaderSrc, NULL );  
    15.      
    16.    // Compile the shader object  
    17.    glCompileShader ( shader );  
    18.   
    19.    // Check the shader object compile status  
    20.    glGetShaderiv ( shader, GL_COMPILE_STATUS, &compiled );  
    21.   
    22.    if ( !compiled )   
    23.    {  
    24.       GLint infoLen = 0;  
    25.   
    26.       glGetShaderiv ( shader, GL_INFO_LOG_LENGTH, &infoLen );  
    27.         
    28.       if ( infoLen > 1 )  
    29.       {  
    30.          char* infoLog = malloc (sizeof(char) * infoLen );  
    31.   
    32.          glGetShaderInfoLog ( shader, infoLen, NULL, infoLog );  
    33.          esLogMessage ( "Error compiling shader: %s ", infoLog );              
    34.            
    35.          free ( infoLog );  
    36.       }  
    37.   
    38.       glDeleteShader ( shader );  
    39.       return 0;  
    40.    }  
    41.   
    42.    return shader;  
    43. }  

    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

    其参考代码如下:

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. GLuint LoadProgram ( const char *vShaderStr, const char *fShaderStr )  
    2. {  
    3.    GLuint vertexShader;  
    4.    GLuint fragmentShader;  
    5.    GLuint programObject;  
    6.    GLint linked;  
    7.   
    8.    // Load the vertex/fragment shaders  
    9.    vertexShader = LoadShader ( GL_VERTEX_SHADER, vShaderStr );  
    10.    fragmentShader = LoadShader ( GL_FRAGMENT_SHADER, fShaderStr );  
    11.   
    12.    // Create the program object  
    13.    programObject = glCreateProgram ( );  
    14.    if ( programObject == 0 )  
    15.       return 0;  
    16.   
    17.    // Attaches a shader object to a program object  
    18.    glAttachShader ( programObject, vertexShader );  
    19.    glAttachShader ( programObject, fragmentShader );  
    20.    // Bind vPosition to attribute 0     
    21.    glBindAttribLocation ( programObject, 0, "vPosition" );  
    22.    // Link the program object  
    23.    glLinkProgram ( programObject );  
    24.   
    25.    // Check the link status  
    26.    glGetProgramiv ( programObject, GL_LINK_STATUS, &linked );  
    27.   
    28.    if ( !linked )   
    29.    {  
    30.       GLint infoLen = 0;  
    31.   
    32.       glGetProgramiv ( programObject, GL_INFO_LOG_LENGTH, &infoLen );  
    33.         
    34.       if ( infoLen > 1 )  
    35.       {  
    36.          char* infoLog = malloc (sizeof(char) * infoLen );  
    37.   
    38.          glGetProgramInfoLog ( programObject, infoLen, NULL, infoLog );  
    39.          esLogMessage ( "Error linking program: %s ", infoLog );              
    40.            
    41.          free ( infoLog );  
    42.       }  
    43.   
    44.       glDeleteProgram ( programObject );  
    45.       return GL_FALSE;  
    46.    }  
    47.    
    48.    // Free no longer needed shader resources  
    49.    glDeleteShader ( vertexShader );  
    50.    glDeleteShader ( fragmentShader );  
    51.   
    52.    return programObject;  
    53. }  

    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的链接,现在还缺少真正供进行编译和链接的源码,其参考代码如下:

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

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

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    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.         
    8.    // Set the viewport  
    9.    glViewport ( 0, 0, esContext->width, esContext->height );  
    10.      
    11.    // Clear the color buffer  
    12.    glClear ( GL_COLOR_BUFFER_BIT );  
    13.   
    14.    // Use the program object  
    15.    glUseProgram ( userData->programObject );  
    16.   
    17.    // Load the vertex data  
    18.    glVertexAttribPointer ( 0, 3, GL_FLOAT, GL_FALSE, 0, vVertices );  
    19.    glEnableVertexAttribArray ( 0 );  
    20.    glDrawArrays ( GL_TRIANGLES, 0, 3 );  
    21.    eglSwapBuffers(esContext->eglDisplay, esContext->eglSurface);  
    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    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处开始的位置数据格式其定义如下:

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    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

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

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    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.   
    9.     memset( &esContext, 0, sizeof( ESContext) );  
    10.     esContext.userData = &userData;  
    11.   
    12.     esContext.width = 1280;  
    13.     esContext.height = 720;  
    14.     // Init EGL display, surface and context  
    15.     if(!InitEGL(&esContext))  
    16.     {  
    17.         printf("Init EGL fail ");  
    18.         return GL_FALSE;  
    19.     }  
    20.     // compile shader, link program   
    21.     if(!CreateProgram(&esContext))  
    22.     {  
    23.         printf("Create Program fail ");  
    24.         return GL_FALSE;  
    25.     }  
    26.   
    27.   
    28.     iStartTime = GetCurTime();  
    29.     iFrames = 0;  
    30.   
    31.     while(1)  
    32.     {    // render a frame  
    33.          Render(&esContext);  
    34.          iFrames++;  
    35.           
    36.          iEndTime = GetCurTime();  
    37.     iDeltaTime  = iEndTime - iStartTime;  
    38.     if(iDeltaTime >= 5000)  
    39.     {  
    40.             iStartTime = iEndTime;  
    41.         float fFrame = iFrames * 1000.0 / iDeltaTime;  
    42.         iFrames = 0;  
    43.   
    44.         printf("Frame: %f ", fFrame);  
    45.     }  
    46.     }  
    47.     glDeleteProgram (esContext.userData->programObject);  
    48.     return GL_TRUE;  
    49. }  
  • 相关阅读:
    【转】Wrapper配置详解及高级应用
    【转】Eclipse4.4.1安装velocity插件Veloeclipse.ui_2.0.8
    【转】创建SVN仓库的步骤
    【转】Hibernate 常见异常
    [转]Java中Map的用法详解
    [转]CocoaPods安装和使用教程
    [转]struts1.2的action参数配置
    [转]hibernateTools工具安装及使用总结(eclipse 3.6)
    [转]iOS开发中@property的属性weak nonatomic strong readonly等介绍
    [转]使用 Xcode 5 和 Interface Builder创建 Hello World App
  • 原文地址:https://www.cnblogs.com/sanjin/p/3580333.html
Copyright © 2011-2022 走看看