android 下使用Direct Texture

要使用Direct Texture,需要有一份android系统的源码
部分C++代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <android/native_window.h>
#include <ui/GraphicBuffer.h>
#include <dlfcn.h>
#include <jni.h>
#include "render_native.h"
 
int  Graphics::initGL(){
 
      const  char const  driver_absolute_path =  "/system/lib/egl/libEGL_mali.so" ;
     // On Gingerbread you have to load symbols manually from Mali driver because
     // Android EGL library has a bug.
     // From  ICE CREAM SANDWICH you can freely use the eglGetProcAddress function.
     // You might be able to get away with just eglGetProcAddress (no dlopen). Tr y it,  else revert to the following code
     void * dso = dlopen(driver_absolute_path, RTLD_LAZY);
     if  (dso != 0)
     {
         LOGI( "dlopen: SUCCEEDED" );
         _eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC)dlsym(dso,  "eglCreateImageKHR" );
         _eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC) dlsym(dso, "eglDestroyImageKHR" );
     }
     else
     {
         LOGI( "dlopen: FAILED! Loading functions in common way!" );
         _eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC) eglGetProcAddress( "eglCreateImageKHR" );
         _eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC) eglGetProcAddress( "eglDestroyImageKHR" );
     }
 
     if (_eglCreateImageKHR == NULL)
     {
         LOGE( "Error: Failed to find eglCreateImageKHR at %s:%in" , __FILE__, __LINE__);
         exit (1);
     }
     if (_eglDestroyImageKHR == NULL)
     {
         LOGE( "Error: Failed to find eglDestroyImageKHR at %s:%in" , __FILE__, __LINE__);
         exit (1);
     }
         _glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) eglGetProcAddress( "glEGLImageTargetTexture2DOES" );
     if (_glEGLImageTargetTexture2DOES == NULL)
     {
         LOGI( "Error: Failed to find glEGLImageTargetTexture2DOES at %s:%in" , __FILE__, __LINE__);
         return  0;
     }
     
     graphicBuffer =  new  GraphicBuffer( emu_width,emu_height,
             HAL_PIXEL_FORMAT_RGBA_8888,
             GraphicBuffer::USAGE_HW_TEXTURE |
             GraphicBuffer::USAGE_HW_2D |
             GRALLOC_USAGE_SW_READ_OFTEN |
             GRALLOC_USAGE_SW_WRITE_OFTEN);
             
     status_t err = graphicBuffer->initCheck();
     if  (err != NO_ERROR)
     {
         LOGI( "Error: %sn" strerror (-err));
         return  0;
     }
     
     GGLSurface t;
     //   graphicBuffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN, &addr);
     graphicBuffer->lock(&t, GRALLOC_USAGE_SW_WRITE_OFTEN);
           
     memset (t.data,128,t.stride*t.height);
     graphicBuffer->unlock();
     
     
     // Retrieve andorid native buffer
     android_native_buffer_t* anb =graphicBuffer->getNativeBuffer();
     // create the new EGLImageKHR
     const  EGLint attrs[] =
     {
         EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
         EGL_NONE, EGL_NONE
     };
     
     mEngine.mTexture.pEGLImage = _eglCreateImageKHR(eglGetCurrentDisplay(),
                                 mEngine.nContext, EGL_NATIVE_BUFFER_ANDROID, (EGLClientBuffer)anb, attrs);
     if (mEngine.mTexture.pEGLImage == EGL_NO_IMAGE_KHR)
     {
         LOGI( "Error: eglCreateImage() failed at %s:%in" , __FILE__, __LINE__);
         return  0;
     }
     checkGlError( "eglCreateImageKHR" );
     LOGI( "create Program......." );
     GLuint gProgram = createProgram(vertex_source, fragment_source);
      checkGlError( "createProgram" );
      if  (!gProgram) {
              LOGE( "Could not create program." );
              return  false ;
           }
      glUseProgram(gProgram);
      vPosition = glGetAttribLocation(gProgram,  "glVertex" );
          checkGlError( "glGetAttribLocation glVertex" );
      glEnableVertexAttribArray(vPosition);
 
     a_texCoord0 = glGetAttribLocation(gProgram,  "a_texCoord0" );
         checkGlError( "glGetAttribLocation texCoord0" );
      glEnableVertexAttribArray(a_texCoord0);
 
      s_tex0 = glGetUniformLocation(gProgram,  "s_texture0" );
         checkGlError( "glGetAttribLocation texture" );
         
     
     
         LOGI( "glGen Textures......." );
     glGenTextures(1, &texID);
     
     glDisable(GL_BLEND);
     glDisable(GL_DEPTH_TEST);
     glDisable(GL_STENCIL_TEST);
     glDisable(GL_DITHER);
     checkGlError( "glDisable" );
//  glEnable(GL_TEXTURE_2D);
//  checkGlError("glEnable(GL_TEXTURE_2D)");
     glGenTextures(1,&texID);
     checkGlError( "glGenTextures" );
      glActiveTexture(GL_TEXTURE0);
     glBindTexture(GL_TEXTURE_2D, texID);
//  glPixelStorei(GL_PACK_ALIGNMENT, 1);
//      glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST  );
         
//       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mEngine.mTexture.nTextureWidth, mEngine.mTexture.nTextureHeight, 0,GL_RGBA, GL_UNSIGNED_BYTE, NULL);
     
//  glFinish();
     _glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,mEngine.mTexture.pEGLImage);
         
      float  w =  float (emu_width)  /  float (mEngine.mTexture.nTextureWidth);
      float  h =  float (emu_height) /  float (mEngine.mTexture.nTextureHeight);
 
          g_pos=initFloatBuffer(vertices,12);
         g_texvbo=initFloatBuffer(texCoords,8);
         
         glViewport(0, 0,  mEngine.nScreen_Width, mEngine.nScreen_Height);
         return  1;
 
}
 
void  Graphics::renderFrame() {
 
//  texture=(unsigned char*)ture;
     glClearColor(0.5f, 0.5f, 0.5f, 1);
     glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
 
      glUniform1i(s_tex0, 0);
      glBindBuffer(GL_ARRAY_BUFFER, g_pos);
      glVertexAttribPointer(vPosition, 3, GL_FLOAT, GL_FALSE, 0, 0);
      glBindBuffer(GL_ARRAY_BUFFER, g_texvbo);
      glVertexAttribPointer(a_texCoord0, 2, GL_FLOAT, GL_FALSE, 0, 0);
     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
     
   eglSwapBuffers(mEngine.nDisplay, mEngine.nSurface);
  
 
void * Graphics::begin(){
     GGLSurface t;
      graphicBuffer->lock(&t,GRALLOC_USAGE_SW_WRITE_OFTEN);
     return  t.data;
}
void  Graphics::end(){
      graphicBuffer->unlock();
      renderFrame();
}
 
 
使用时如下:
Graphics  render;
 
 
void  *buffer=render.begin();
把数据填充到buffer里
render.end();
 
编译时包含头文件
LOCAL_C_INCLUDES +=
     $(ANDROID_SRC_HOME)/frameworks/base/core/jni/android/graphics 
     $(ANDROID_SRC_HOME)/frameworks/base/include/
     $(ANDROID_SRC_HOME)/hardware/libhardware/include
     $(ANDROID_SRC_HOME)/ system /core/include
     $(ANDROID_SRC_HOME)/frameworks/base/native/include/
     $(ANDROID_SRC_HOME)/frameworks/base/opengl/include/
 
链接选项:
LOCAL_LDLIBS    := -llog -lGLESv2 -lEGL -landroid  -lui -landroid_runtime  -ljnigraphics
 
android  Opengles 里虽然没有PBO, 但是用Direct Texture能实现类似的功能。
 
direct textures 的使用介绍
http: //snorp.net/2011/12/16/android-direct-texture.html
 
eglCreateImageKHR扩展的介绍
http: //www.khronos.org/registry/egl/extensions/KHR/EGL_KHR_image_base.txt

描述:在opengles 编程时如果用glTexImage2D /glTexSubImage2D API的话,当渲染的图片很大时,速度会变得很慢的,因为运行时会发生数据拷贝的过程,而使用opengles 的扩展glEGLImageTargetTexture2DOES可以解决这个问题,用这个扩展要用到另一个扩展 eglCreateImageKHR 。

你可能感兴趣的:(android)