2012-07-11 3 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; 
} 

어려움에 봉착 목표 C에서, 당신은 단지 이러한 방법을 호출 할 수 보이지만 자바 당신은 할 수 없습니다. 일부 검색을 수행했는데 대부분의 사람들이 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, size, 0); ? – cleuton

답변

1

하지만 문제는 제대로 EGLContext를 초기화하지 않은 것입니다 : 그것은 도움이 될 것입니다 경우

, 여기에 내 현재 코드입니다.

일반적으로 GLSurfaceView 또는 TextureView를 사용하여 실제로 GL 계층을 View 계층에 포함하고자 할 것입니다. GLSurfaceView는 EGLContext를 적절하게 만들고 렌더 스레드를 관리하는 것과 같이 많은 일들을 처리 할 것입니다. TextureView는 좀 더 수동 작업이 필요합니다. 이러한 방법 중 하나를 통해 컨텍스트가되면

, 당신은 사용할 수 있습니다

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

당신이는 OpenGL ES 2.0 API를 구속 한 가정. 먼저 EGLContext를 올바르게 작성했는지 확인하고 EGL 및 GLES 호출을 실행할 수 있으며 최대 텍스처 크기를 쿼리 할 수 ​​있어야합니다.

당신이 GLSurfaceView가 ( https://groups.google.com/d/msg/android-developers/U5RXFGpAHPE/IqHeIeGXhr0J) 여기에 자신 EGLContext 관리에 대한 핵심적으로 견실 한 세부 정보를 볼 것처럼 당신은 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