2012-07-11 21 views
6

Androidアプリケーションで使用できるように、このObjective C GPUImage FrameworkのオープンソースJavaポートを作成するように割り当てられました。私はすべての変数名、関数名などをすべて同じようにできるだけ再現したいと思います。私は初期段階にあり、私はGPUImageOpenGLESContext.hとGPUImageOpenGLESContext.mを移植しようとしています(申し訳ありませんが、リンクを提供しますが、新しいユーザーとして私はリンクを追加できません)。Android OpenGLESの最大/最小テクスチャサイズ制限の決定

私はこれらのメソッド

+ (GLint)maximumTextureSizeForThisDevice; 
{ 
    GLint maxTextureSize; 
    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize); 
    return maxTextureSize; 
} 

+ (GLint)maximumTextureUnitsForThisDevice; 
{ 
    GLint maxTextureUnits; 
    glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits); 
    return maxTextureUnits; 
} 

の難しさを抱えていることは、Objective Cの中で、あなたは、単にこれらのメソッドを呼び出すことができるようですが、Javaでは、あなたがすることはできません。私はいくつかの検索を行い、ほとんどの人がGLSurfaceViewを使用すると言いましたが、これにはアクティビティが必要ですか?このGet Maximum OpenGL ES 2.0 Texture Size Limit on Androidが見つかりましたが、私は非常に興奮しましたが、応答はコードが機能しないと主張しています。

私の質問は、どのようにして、アクティビティではないクラスの最小と最大のテクスチャを得ることができるのですか? GLSurfaceViewを使用しますか?

これを移植する方法についてのご意見もありがとうございます。私はObjective CからJavaへの移植は一度もしていないので、アドバイスをいただければ幸いです!

それが参考になる場合は、ここに私の現在のコードは次のとおりです。

public class GPUImageOpenGLESContext 
{ 
    private static GPUImageOpenGLESContext instance = null; 

    EGLContext context; 

    protected GPUImageOpenGLESContext() 
    { 
     // This is a protected empty method 
     // that exists only to prevent 
     // this singleton object from 
     // multiple instantiation 

     return; 
    } 

    public enum GPUImageRotationMode { 
      kGPUImageNoRotation, kGPUImageRotateLeft, kGPUImageRotateRight, kGPUImageFlipVertical, 
      kGPUImageFlipHorizontal, kGPUImageRotateRightFlipVertical, kGPUImageRotate180 
    } 

    public GPUImageRotationMode GPUImageRotationSwapsWidthAndHeight(GPUImageRotationMode rotation) 
    { 
     // TODO: Implement GPUImageRotationSwapsWidthAndHeight macro as method 
     //rotation = ((rotation) == kGPUImageRotateLeft || (rotation) == kGPUImageRotateRight || (rotation) == kGPUImageRotateRightFlipVertical) 
     return rotation; 
    } 

    public static GPUImageOpenGLESContext sharedImageProcessingOpenGLESContext() 
    { 
     if (instance == null) 
     { 
      instance = new GPUImageOpenGLESContext(); 
     } 
     return instance; 
    } 

    public static void useImageProcessingContext() 
    { 
     EGLContext imageProcessingContext = GPUImageOpenGLESContext.sharedImageProcessingOpenGLESContext().context; 
     if (EGLContext.getEGL() != imageProcessingContext) 
     { 
      // In Objective C, this call would be here: 
      // [EAGLContext setCurrentContext:imageProcessingContext] 

      // Cannot figure out how to handle this. For now, throws an exception. 
      throw new RuntimeException("useImageProcessingContext not equal to EGLContext"); 
     } 

     return; 
    } 

    public static int maximumTextureSizeForThisDevice() 
    { 
     int[] maxTextureSize = new int[1]; 

     // TODO: See if you can use gl. without an activity 
     //GL10 gl = new GL10(); 
     //EGL gl = EGLContext.getEGL(); 

     //gl.glGetIntegerv(GL10.GL_MAX_TEXTURE_SIZE, maxTextureSize, 0); 

     return maxTextureSize[0]; 
    } 

    public static int maximumTextureUnitsForThisDevice() 
    { 
     // TODO: Implement maximumTextureUnitsForThisDevice(); 
     return -1; 
    } 

    public static CGSize sizeThatFitsWithinATextureForSize(CGSize inputSize) 
    { 
     int maxTextureSize = maximumTextureSizeForThisDevice(); 

     if ((inputSize.width < maxTextureSize) && (inputSize.height < maxTextureSize)) 
     { 
      return inputSize; 
     } 

     CGSize adjustedSize = new CGSize(); 
     if (inputSize.width > inputSize.height) 
     { 
      adjustedSize.width = (float)maxTextureSize; 
      adjustedSize.height = ((float)maxTextureSize/inputSize.width) * inputSize.height; 
     } 
     else 
     { 
      adjustedSize.height = (float)maxTextureSize; 
      adjustedSize.width = ((float)maxTextureSize/inputSize.height) * inputSize.width; 
     } 

     return adjustedSize; 
    } 

    public EGLContext getContext() 
    { 
     if (context == null) 
     { 
      // TODO: Implement getContext() 
     } 
    } 

    public interface GPUImageInput 
    { 
     public void newFrameReadyAtTime(Time frameTime); 
     public void setInputTextureAtIndex(int newInputTexture, int textureIndex); 
     public int nextAvailableTextureIndex(); 
     public void setInputSizeAtIndex(CGSize newSize, int textureIndex); 
     public void setInputRotationAtIndex(GPUImageRotationMode newInputRotation, int textureIndex); 
     public CGSize maximumOutputSize(); 
     public void endProcessing(); 
     public boolean shouldIgnoreUpdatesToThisTarget(); 
    } 
} 
+0

完了したら、この人にそのことを知らせてください:http://stackoverflow.com/questions/11405207/gpuimage-port-for-android –

+0

GLES20.glGetIntegervを試しましたか(GLES20.GL_MAX_TEXTURE_SIZE、サイズ、 0)。 ? – cleuton

答えて

1

私はこれは古い記事ですが、あなたの問題はあなたが適切EGLContextを初期化していないことであると認識。

通常、GLSurfaceViewまたはTextureViewを使用して、実際にGLコンテンツをビュー階層に含めることができます。 GLSurfaceViewは、EGLContextを適切に作成してレンダリングスレッドを管理するなど、多くのことを処理します。 TextureViewにはもう少し手作業が必要です。

あなたはこれらの手段のいずれかによってコンテキストを持っていたら、使用することができます。

GLES20.glGetIntegerv(GLES20.GL_MAX_TEXTURE_SIZE, size, 0); 

あなたは、OpenGL ES 2.0 APIを拘束していると仮定。最初にEGLContextを適切に作成し、EGLとGLES呼び出しを実行できることを確認してから、最大テクスチャサイズを問い合わせる必要があります。

あなたはGLSurfaceViewここにあなた自身のEGLContextの管理に関する核心ザラザラの詳細(https://groups.google.com/d/msg/android-developers/U5RXFGpAHPE/IqHeIeGXhr0J)を参照するだろうあなたとTextureViewの使用についてのロマン・ガイの投稿を見ることができます:

GLSurfaceViewは、あなたのためのGLのセットアップを処理するTextureViewしません。 EGL サーフェスを作成すると、TextureViewをネイティブウィンドウとして使用できます。ここでは一例である(興味深い部分は eglCreateWindowSurface()の呼び出しである):

@Override 
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { 
    mRenderThread = new RenderThread(getResources(), surface); 
    mRenderThread.start(); 
} 

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; 

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

    private static final String sSimpleVS = 
      "attribute vec4 position;\n" + 
      "attribute vec2 texCoords;\n" + 
      "varying vec2 outTexCoords;\n" + 
      "\nvoid main(void) {\n" + 
      " outTexCoords = texCoords;\n" + 
      " gl_Position = position;\n" + 
      "}\n\n"; 
    private static final String sSimpleFS = 
      "precision mediump float;\n\n" + 
      "varying vec2 outTexCoords;\n" + 
      "uniform sampler2D texture;\n" + 
      "\nvoid main(void) {\n" + 
      " gl_FragColor = texture2D(texture, outTexCoords);\n" + 
      "}\n\n"; 

    private static final int FLOAT_SIZE_BYTES = 4; 
    private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES; 
    private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0; 
    private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3; 
    private final float[] mTriangleVerticesData = { 
      // X, Y, Z, U, V 
      -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 
      1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 
      -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 
      1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 
    }; 

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

     FloatBuffer triangleVertices = ByteBuffer.allocateDirect(mTriangleVerticesData.length 
       * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer(); 
     triangleVertices.put(mTriangleVerticesData).position(0); 

     int texture = loadTexture(R.drawable.large_photo); 
     int program = buildProgram(sSimpleVS, sSimpleFS); 

     int attribPosition = glGetAttribLocation(program, "position"); 
     checkGlError(); 

     int attribTexCoords = glGetAttribLocation(program, "texCoords"); 
     checkGlError(); 

     int uniformTexture = glGetUniformLocation(program, "texture"); 
     checkGlError(); 

     glBindTexture(GL_TEXTURE_2D, texture); 
     checkGlError(); 

     glUseProgram(program); 
     checkGlError(); 

     glEnableVertexAttribArray(attribPosition); 
     checkGlError(); 

     glEnableVertexAttribArray(attribTexCoords); 
     checkGlError(); 

     glUniform1i(uniformTexture, texture); 
     checkGlError(); 

     while (!mFinished) { 
      checkCurrent(); 

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

      glClear(GL_COLOR_BUFFER_BIT); 
      checkGlError(); 

      // drawQuad 
      triangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET); 
      glVertexAttribPointer(attribPosition, 3, GL_FLOAT, false, 
        TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices); 

      triangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET); 
      glVertexAttribPointer(attribTexCoords, 3, GL_FLOAT, false, 
        TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices); 

      glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 

      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 int buildProgram(String vertex, String fragment) { 
     int vertexShader = buildShader(vertex, GL_VERTEX_SHADER); 
     if (vertexShader == 0) return 0; 

     int fragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER); 
     if (fragmentShader == 0) return 0; 

     int program = glCreateProgram(); 
     glAttachShader(program, vertexShader); 
     checkGlError(); 

     glAttachShader(program, fragmentShader); 
     checkGlError(); 

     glLinkProgram(program); 
     checkGlError(); 

     int[] status = new int[1]; 
     glGetProgramiv(program, GL_LINK_STATUS, status, 0); 
     if (status[0] != GL_TRUE) { 
      String error = glGetProgramInfoLog(program); 
      Log.d(LOG_TAG, "Error while linking program:\n" + error); 
      glDeleteShader(vertexShader); 
      glDeleteShader(fragmentShader); 
      glDeleteProgram(program); 
      return 0; 
     } 

     return program; 
    } 

    private int buildShader(String source, int type) { 
     int shader = glCreateShader(type); 

     glShaderSource(shader, source); 
     checkGlError(); 

     glCompileShader(shader); 
     checkGlError(); 

     int[] status = new int[1]; 
     glGetShaderiv(shader, GL_COMPILE_STATUS, status, 0); 
     if (status[0] != GL_TRUE) { 
      String error = glGetShaderInfoLog(shader); 
      Log.d(LOG_TAG, "Error while compiling shader:\n" + error); 
      glDeleteShader(shader); 
      return 0; 
     } 

     return shader; 
    } 

    private void checkEglError() { 
     int error = mEgl.eglGetError(); 
     if (error != EGL10.EGL_SUCCESS) { 
      Log.w(LOG_TAG, "EGL error = 0x" + Integer.toHexString(error)); 
     } 
    } 

    private 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 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; 
    } 
} 

あなたが持っている可能性もNDKルートを行ってきましたが、それはおそらく客観C.

からより簡単移行だろう
+0

ありがとう!残念ながら、私はもはやこのプロジェクトに取り組んでいませんが、質問に答える時間を割いていただき、ありがとうございます。 – Synergy807

関連する問題