2015-01-07 50 views
2

我是新来的opengl ES,我想在TextureView上渲染开放的gl视图。如何在TextureView中绘制立方体Android

这里是立方体图的样本开放式GL例如https://gist.github.com/ybakos/4151696
但是,当我试图绘制使用TextureView相同的立方体 ,

我不能够得出这样的立方体。 指导我如何使用TextureView绘制opengl立方体。

下面是示例代码::

public class DemoGraphicGlctivity extends Activity implements TextureView.SurfaceTextureListener { 
    private RenderThread mRenderThread; 
    private TextureView mTextureView; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     mTextureView = new TextureView(this); 
     mTextureView.setSurfaceTextureListener(this); 
     setContentView(mTextureView, new FrameLayout.LayoutParams(
       ViewGroup.LayoutParams.MATCH_PARENT, 400)); 
    } 
    @Override 
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { 
     mRenderThread = new RenderThread(getResources(), surface, DemoGraphicGlctivity.this); 
     mRenderThread.start(); 
    } 

    @Override 
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { 
    } 
    @Override 
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { 
     mRenderThread.finish(); 
     try { 
      mRenderThread.join(); 
     } catch (InterruptedException e) { 
      Log.e(RenderThread.LOG_TAG, "Could not wait for render thread"); 
     } 
     return true; 
    } 
    @Override 
    public void onSurfaceTextureUpdated(SurfaceTexture surface) { 
    } 
    private static class RenderThread extends Thread { 
     private static final String LOG_TAG = "GLTextureView"; 
     static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098; 
     static final int EGL_OPENGL_ES2_BIT = 4; 
     private volatile boolean mFinished; 
     private final Resources mResources; 
     private final SurfaceTexture mSurface; 

     private EGL10 mEgl; 
     private EGLDisplay mEglDisplay; 
     private EGLConfig mEglConfig; 
     private EGLContext mEglContext; 
     private EGLSurface mEglSurface; 
     private GL mGL; 
     Context context; 

     RenderThread(Resources resources, SurfaceTexture surface, Context mContext) { 
      mResources = resources; 
      mSurface = surface; 
      context = mContext; 
     } 

     @Override 
     public void run() { 
      initGL(); 

     // vertices 
      FloatBuffer vertexBuffer = ByteBuffer 
        .allocateDirect(CubeConstant.vertices.length * 4) 
        .order(ByteOrder.nativeOrder()).asFloatBuffer(); 
      vertexBuffer.put(CubeConstant.vertices); 
      vertexBuffer.position(0); 

      // texture map 
      FloatBuffer textureBuffer = ByteBuffer 
        .allocateDirect(CubeConstant.texture.length * 4) 
        .order(ByteOrder.nativeOrder()).asFloatBuffer(); 
      textureBuffer.put(CubeConstant.texture); 
      textureBuffer.position(0); 

      // indices 
      ByteBuffer indexBuffer = ByteBuffer.allocateDirect(CubeConstant.indices.length); 
      indexBuffer.put(CubeConstant.indices); 
      indexBuffer.position(0); 


      int texture = loadTexture(R.drawable.receipt_bg); 

      //int program = buildProgram(sSimpleVS, sSimpleFS); 
      int program = ShaderHelper 
        .linkProgram(ShaderHelper 
          .compileVertexShader(TextResourceReader 
            .readTextFileFromResource(context, 
              R.raw.cube_vertex)), ShaderHelper 
          .compileFragmentShader(TextResourceReader 
            .readTextFileFromResource(context, 
              R.raw.cube_fragment))); 



      int aPositionLocation = glGetAttribLocation(program, "a_Position"); 
      checkGlError(); 

      int aTextureCoordinatesLocation = glGetAttribLocation(program, "a_TextureCoordinates"); 
      checkGlError(); 



      glBindTexture(GL_TEXTURE_2D, texture); 
      checkGlError(); 

      glUseProgram(program); 
      checkGlError(); 

      glVertexAttribPointer(aPositionLocation, 3 , GL_FLOAT, false , 0, vertexBuffer); 
      checkGlError(); 

      vertexBuffer.position(0); 
      glVertexAttribPointer(aPositionLocation, 3 , GL_FLOAT, false , 0, vertexBuffer); 
      glEnableVertexAttribArray(aPositionLocation); 
      textureBuffer.position(0); 
      glVertexAttribPointer(aTextureCoordinatesLocation, 2, GL_FLOAT, false, 0, textureBuffer); 
      glEnableVertexAttribArray(aTextureCoordinatesLocation); 
      checkGlError(); 


      glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 
      checkGlError(); 

      while (!mFinished) { 
       checkCurrent(); 
       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
       checkGlError(); 

       glBindTexture(GL_TEXTURE_2D, texture); 
       glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indexBuffer); 

       if (!mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) { 
        throw new RuntimeException("Cannot swap buffers"); 
       } 
       checkEglError(); 
       try { 
        Thread.sleep(2000); 
       } catch (InterruptedException e) { 
        // Ignore 
       } 
      } 
      finishGL(); 
     } 
     private int loadTexture(int resource) { 
      int[] textures = new int[1]; 
      glActiveTexture(GL_TEXTURE0); 
      glGenTextures(1, textures, 0); 
      checkGlError(); 
      int texture = textures[0]; 
      glBindTexture(GL_TEXTURE_2D, texture); 
      checkGlError(); 

      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
      Bitmap bitmap = BitmapFactory.decodeResource(mResources, resource); 
      GLUtils.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bitmap, GL_UNSIGNED_BYTE, 0); 
      checkGlError(); 
      bitmap.recycle(); 
      return texture; 
     } 


     private void checkEglError() { 
      int error = mEgl.eglGetError(); 
      if (error != EGL10.EGL_SUCCESS) { 
       Log.w(LOG_TAG, "EGL error = 0x" + Integer.toHexString(error)); 
      } 
     } 
     private static void checkGlError() { 
      int error = glGetError(); 
      if (error != GL_NO_ERROR) { 
       Log.w(LOG_TAG, "GL error = 0x" + Integer.toHexString(error)); 
      } 
     } 
     private void finishGL() { 
      mEgl.eglDestroyContext(mEglDisplay, mEglContext); 
      mEgl.eglDestroySurface(mEglDisplay, mEglSurface); 
     } 
     private void checkCurrent() { 
      if (!mEglContext.equals(mEgl.eglGetCurrentContext()) || 
        !mEglSurface.equals(mEgl.eglGetCurrentSurface(EGL10.EGL_DRAW))) { 
       if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) { 
        throw new RuntimeException("eglMakeCurrent failed " 
          + GLUtils.getEGLErrorString(mEgl.eglGetError())); 
       } 
      } 
     } 

     private void initGL() { 
      mEgl = (EGL10) EGLContext.getEGL(); 
      mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); 
      if (mEglDisplay == EGL10.EGL_NO_DISPLAY) { 
       throw new RuntimeException("eglGetDisplay failed " 
         + GLUtils.getEGLErrorString(mEgl.eglGetError())); 
      } 

      int[] version = new int[2]; 
      if (!mEgl.eglInitialize(mEglDisplay, version)) { 
       throw new RuntimeException("eglInitialize failed " + 
         GLUtils.getEGLErrorString(mEgl.eglGetError())); 
      } 
      mEglConfig = chooseEglConfig(); 
      if (mEglConfig == null) { 
       throw new RuntimeException("eglConfig not initialized"); 
      } 

      mEglContext = createContext(mEgl, mEglDisplay, mEglConfig); 
      mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay, mEglConfig, mSurface, null); 
      if (mEglSurface == null || mEglSurface == EGL10.EGL_NO_SURFACE) { 
       int error = mEgl.eglGetError(); 
       if (error == EGL10.EGL_BAD_NATIVE_WINDOW) { 
        Log.e(LOG_TAG, "createWindowSurface returned EGL_BAD_NATIVE_WINDOW."); 
        return; 
       } 
       throw new RuntimeException("createWindowSurface failed " 
         + GLUtils.getEGLErrorString(error)); 
      } 
      if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) { 
       throw new RuntimeException("eglMakeCurrent failed " 
         + GLUtils.getEGLErrorString(mEgl.eglGetError())); 
      } 
      mGL = mEglContext.getGL(); 
     } 

     EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) { 
      int[] attrib_list = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE }; 
      return egl.eglCreateContext(eglDisplay, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);    
     } 
     private EGLConfig chooseEglConfig() { 
      int[] configsCount = new int[1]; 
      EGLConfig[] configs = new EGLConfig[1]; 
      int[] configSpec = getConfig(); 
      if (!mEgl.eglChooseConfig(mEglDisplay, configSpec, configs, 1, configsCount)) { 
       throw new IllegalArgumentException("eglChooseConfig failed " + 
         GLUtils.getEGLErrorString(mEgl.eglGetError())); 
      } else if (configsCount[0] > 0) { 
       return configs[0]; 
      } 
      return null; 
     } 

     private static int[] getConfig() { 
      return new int[] { 
        EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 
        EGL10.EGL_RED_SIZE, 8, 
        EGL10.EGL_GREEN_SIZE, 8, 
        EGL10.EGL_BLUE_SIZE, 8, 
        EGL10.EGL_ALPHA_SIZE, 8, 
        EGL10.EGL_DEPTH_SIZE, 0, 
        EGL10.EGL_STENCIL_SIZE, 0, 
        EGL10.EGL_NONE 
      }; 
     } 
     void finish() { 
      mFinished = true; 
     } 
    } 
} 

请让我知道我错了....

+0

我遇到同样的问题。我想绘制纹理视图的立方体。请为上述问题提供解决方案 –

回答

0

我不知道很多,但我的事情,你必须在罗曼这个家伙的说明: 创建一个OpenGL上下文

  1. 生成一个OpenGL纹理名称。
  2. 使用纹理名称创建SurfaceTexture。
  3. 将SurfaceTexture传递给相机。
  4. 收听更新。
  5. 在SurfaceTexture更新上,使用您要的着色器 使用OpenGL绘制纹理。