egl gles2.0开发

在android中,java层需要创建surface,

class MobileViewGLES extends GLSurfaceView implements Callback
{
   public void surfaceCreated(SurfaceHolder holder)
    {
        Log.e("MobileViewGLES", "surfaceCreated"); 
        //new Thread(this).start();
        initRenderGLES( getHolder().getSurface() );
    } 
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
    {   
        Log.e("MobileViewGLES", "surfaceChanged"); 
    }
    public void surfaceDestroyed(SurfaceHolder holder) 
    { 
        Log.e("MobileViewGLES", "surfaceDestroyed"); 
        termRenderGLES();
    } 
    public native void initRenderGLES( Surface surface );
    
    public native void termRenderGLES();
}

initRenderGLES是Native函数,在c++层实现,该函数主要创建gles环境,绘制的surface和display,实现函数如下:

static void MobileViewGLES_InitRenderGLES( JNIEnv *env, jobject thiz, jobject surface )
{
    gANativeWindow = ANativeWindow_fromSurface( env, surface );

    GlesInitDisplay();
    CreateGlesEnv();
    GlesEnvChanged( gWidth, gHeight );
    SetDrawOffScreen( false );
    //GlesDrawFrame();
    //GlesTermDisplay();
    return;

}
GlesInitDisplay()如下:
int GlesInitDisplay()
{
    const EGLint attribs[] =
    {
        EGL_SURFACE_TYPE,
        EGL_WINDOW_BIT,
        EGL_BLUE_SIZE, 8,
        EGL_GREEN_SIZE, 8,
        EGL_RED_SIZE, 8,
        EGL_NONE
    };
    EGLConfig config;
    EGLint numConfigs;
    EGLint format;
    EGLint width;
    EGLint height;
    EGLint contextAtt[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, EGL_NONE };

    gDisplay = eglGetDisplay( EGL_DEFAULT_DISPLAY );
    eglInitialize( gDisplay, 0, 0 );
    eglChooseConfig( gDisplay, attribs, &config, 1, &numConfigs );
    eglGetConfigAttrib( gDisplay, config, EGL_NATIVE_VISUAL_ID, &format );
    ANativeWindow_setBuffersGeometry( gANativeWindow, 0, 0, format);

    gSurface = eglCreateWindowSurface( gDisplay, config, gANativeWindow, NULL);
    gContext = eglCreateContext( gDisplay, config, EGL_NO_CONTEXT, contextAtt);
    if (eglMakeCurrent( gDisplay, gSurface, gSurface, gContext) == EGL_FALSE)
    {
        LOGE("Unable to eglMakeCurrent");
        return -1;
    }

    eglQuerySurface( gDisplay, gSurface, EGL_WIDTH, &width );
    eglQuerySurface( gDisplay, gSurface, EGL_HEIGHT, &height );

    return 0;
}

GLint CreateGlesEnv( )
{
    static char vShaderStr[] =
        "uniform mat4 u_TransMatrix;                    
"
        "attribute vec4 a_position;                       
"
        "attribute vec2 a_texCoord;                       
"
        "varying vec2 v_texCoord;                         
"
        "void main()                                      
"
        "{                                                
"
        "   gl_Position = u_TransMatrix * a_position;     
"
        "   v_texCoord = a_texCoord;                      
"
        "}                                                
";

    static char fShaderStr[] =
      "precision mediump float;                                    
"
      "varying vec2 v_texCoord;                                     
"
      "uniform sampler2D s_ImgTexture;                             
"
      "uniform int specColorFlag;                                    
"
      "uniform vec4 specColor;                                        
"
      "void main()                                                 
"
      "{                                                           
"
      //"       gl_FragColor = texture2D( s_ImgTexture, v_texCoord );
"
      " if (specColorFlag == 0)                                 
"
      " {gl_FragColor = texture2D( s_ImgTexture, v_texCoord );} 
"
      " else {gl_FragColor = specColor;}                         
"
      "}                                                           
";

    //esOrtho(&gOrthographic, -100, 100, -100, 100, 5.0f, -5.0f );


    GLuint vertexShader;
    GLuint fragmentShader;
    GLuint programObject;
    GLint linked;

    // Load the vertex/fragment shaders
    vertexShader = esLoadShader ( GL_VERTEX_SHADER, vShaderStr );
    if ( vertexShader == 0 )
      return 0;

    fragmentShader = esLoadShader ( GL_FRAGMENT_SHADER, fShaderStr );
    if ( fragmentShader == 0 )
    {
      glDeleteShader( vertexShader );
      return 0;
    }

    gProObject = glCreateProgram ( );

    glAttachShader ( gProObject, vertexShader );
    glAttachShader ( gProObject, fragmentShader );

    // Link the program
    glLinkProgram ( gProObject );

    // Check the link status
    glGetProgramiv ( gProObject, GL_LINK_STATUS, &linked );

    if ( !linked )
    {
      GLint infoLen = 0;

      glGetProgramiv ( gProObject, GL_INFO_LOG_LENGTH, &infoLen );

      if ( infoLen > 1 )
      {
         char* infoLog = (char *)malloc (sizeof(char) * infoLen );

         glGetProgramInfoLog ( gProObject, infoLen, NULL, infoLog );
         free ( infoLog );
      }

      glDeleteProgram ( gProObject );
      return 0;
    }

    // Free up no longer needed shader resources
    glDeleteShader ( vertexShader );
    glDeleteShader ( fragmentShader );

    gShaderPosition = glGetAttribLocation ( gProObject, "a_position" );
    gShaderTexCoord = glGetAttribLocation ( gProObject, "a_texCoord" );

    gvpMatrix          = glGetUniformLocation( gProObject, "u_TransMatrix" );
    gShaderImgTexture = glGetUniformLocation ( gProObject, "s_ImgTexture" );

    gColorFlag        = glGetUniformLocation( gProObject, "specColorFlag" );
    gColorLoc        = glGetUniformLocation( gProObject, "specColor" );

    //glEnable (GL_BLEND);
    //glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_COLOR);

    glGenTextures(1, &gMainTexture );
    glGenTextures(1, &gTextureTmp);

    GlesBindOffScreen();

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glBindTexture(GL_TEXTURE_2D, gTextureTmp);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
    glTexImage2D(GL_TEXTURE_2D,
            0,
            GL_RGBA,
            gWidth,
            gHeight,
            0,
            GL_RGBA,
            GL_UNSIGNED_BYTE,
            NULL );

    return gProObject;
}
void GlesEnvChanged(  int width, int height )
{
    gWidthd2 = width / 2;
    gHeightd2 = height / 2;

    esMatrixLoadIdentity( &gOrthographic );
    //esOrtho(&gOrthographic, 0, mWidth, -mHeight, 0, 5.0f, -5.0f );
    esOrtho(&gOrthographic, -gWidthd2, gWidthd2, -gHeightd2, gHeightd2, 5.0f, -5.0f );

    ESMatrix modelview;
    esMatrixLoadIdentity( &gMatrix );
    esMatrixLoadIdentity( &modelview );
    esMatrixMultiply( &gMatrix, &modelview, &gOrthographic );

    glViewport(0, 0, width, height);
}

void SetDrawOffScreen(bool bOffScreen )
{
    if ( bOffScreen )
    {
        glBindFramebuffer(GL_FRAMEBUFFER, gFrameBuffer);
    }
    else
    {
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
    }
}
通过上面步骤,gles环境创建完成,下面就是绘制
        case XWM_REPAINT:
        {
            if( eglMakeCurrent( gDisplay, gSurface, gSurface, gContext) == EGL_FALSE )
            {
                LOGWHEREMSG("MakeCurrent Error");
                break;
            }
            LOGWHEREMSG( "XWM_REPAINT" );
            XRect clip(m_clip);
            glClearColor( 0.0f, 0.0f,  0.0f, 1.0f );
            glBindFramebuffer(GL_FRAMEBUFFER, gFrameBuffer);
            bool b = Paint(m_draw);
            if( b )
            {
                glClearColor( 0.0f, 0.0f,  0.0f, 1.0f );
                glBindFramebuffer(GL_FRAMEBUFFER, 0);
                GlesPaint( gMainTexture );
                FlushBuffer();
                LOGWHEREMSG( "XWM_REPAINT" );
            }
            else
            {
                InvalidateRect(clip);
            }
            break;
        }

绘制过程中,glBindFramebuffer(GL_FRAMEBUFFER, gFrameBuffer)设置绘制在离屏缓存区上,  而glBindFramebuffer(GL_FRAMEBUFFER, 0)则绘制在屏幕上

最后,在结束时通过调用termRenderGLES()函数,销毁surface,函数实现如下:

int GlesTermDisplay()
{
    if( gDisplay != EGL_NO_DISPLAY )
    {
        eglMakeCurrent( gDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
        if( gContext != EGL_NO_CONTEXT )
        {
            eglDestroyContext( gDisplay, gContext );
        }
        if( gSurface != EGL_NO_SURFACE )
        {
            eglDestroySurface( gDisplay, gDisplay );
        }
        eglTerminate( gDisplay );
    }
}


原文地址:https://www.cnblogs.com/Anzhongliu/p/6092092.html