2016-06-28 1 views
1

SurfaceView를 사용하여 GLES를 통해 카메라 미리보기를 화면에 렌더링합니다. 렌더링되기 전에 아래의 메서드에서 텍스처를자를 수 있습니까? 16 : 9 텍스처를 화면에 4 : 3으로 표시하려고합니다.그리기 전에 GLES 텍스처 자르기

public void drawFrame(int width, int height, float sourceAspectRatio, float targetAspectRatio, boolean flipHorizontally, boolean flipVertically) { 

    //Aspect ratio correction. Source Aspect ratio is taken from Camera.Parameters.getPictureSize() 
    //assuming that value is the native resolution of the camera. Sometimes the native camera aspect ratio 
    //doesn't match the display's aspect ratio. 
    float scaleX, scaleY; 
    if (sourceAspectRatio >= targetAspectRatio) { 
     scaleX = sourceAspectRatio/targetAspectRatio; 
     scaleY = 1; 
    } else { 
     scaleX = 1; 
     scaleY = targetAspectRatio/sourceAspectRatio; 
    } 

    if (flipHorizontally) scaleX = -scaleX; 
    if (flipVertically) scaleY = -scaleY; 

    checkGlError("onDrawFrame start"); 
    mSurfaceTexture.getTransformMatrix(mSTMatrix); 

    GLES20.glViewport(0,0,width,height); 

    GLES20.glClearColor(0.0f, 1.0f, 0.0f, 1.0f); 
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); 

    GLES20.glUseProgram(mProgram); 
    checkGlError("glUseProgram"); 

    /** 
    * Explanation of double binding: http://stackoverflow.com/questions/20386515/glsurfaceview-framerate-issues-on-nexus-5 
    * 
    * I was able to replicate the behavior, and my GL wizard office-mate figured out the problem. 
    * Basically, one of the EGL contexts isn't noticing that the texture contents have changed, so it keeps rendering older data. 
    * We think it's getting occasional updates because it has a set of buffers that it cycles through, 
    * so eventually it re-uses the buffer you're looking at. 
    * I was able to fix the problem in my code by updating the texture renderer class, changing this: 
    * 
    * GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureID) 
    * 
    * to this 
    * 
    * GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0); 
    * GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureID); 
    * 
    * The un-bind and re-bind causes the driver to pick up the right buffer. 
    */ 
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 
    GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0); 
    GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureID); 

    mTriangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET); 
    GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices); 
    checkGlError("glVertexAttribPointer maPosition"); 
    GLES20.glEnableVertexAttribArray(maPositionHandle); 
    checkGlError("glEnableVertexAttribArray maPositionHandle"); 

    mTriangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET); 
    GLES20.glVertexAttribPointer(maTextureHandle, 2, GLES20.GL_FLOAT, false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices); 
    checkGlError("glVertexAttribPointer maTextureHandle"); 
    GLES20.glEnableVertexAttribArray(maTextureHandle); 
    checkGlError("glEnableVertexAttribArray maTextureHandle"); 
    Matrix.setIdentityM(mMVPMatrix, 0); 
    mMVPMatrix[0] = scaleX; 
    mMVPMatrix[5] = scaleY; 
    GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0); 
    GLES20.glUniformMatrix4fv(muSTMatrixHandle, 1, false, mSTMatrix, 0); 

    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); 
    checkGlError("glDrawArrays"); 

    GLES20.glDisableVertexAttribArray(maTextureHandle); 
    GLES20.glDisableVertexAttribArray(maPositionHandle); 
    GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0); 
    GLES20.glUseProgram(0); 
} 

답변

0

좋아, 나는 이것이 텍스처를 자르는 올바른 방법이라고 확신하지만, 내가 필요한 것을 수행한다. 뷰포트의 시작 좌표에 음수 값을 설정하고 필요한 출력에 따라 해상도를 조정합니다.

public void drawFrame(int sourceWidth, int sourceHeight, int targetWidth, int targetHeight, boolean flipHorizontally, boolean flipVertically) { 

    int offsetX = 0, offsetY = 0; 
    float scaleX = 1, scaleY = 1; 
    if (flipHorizontally) scaleX = -scaleX; 
    if (flipVertically) scaleY = -scaleY; 

    float sourceAspectRatio = (float) sourceWidth/sourceHeight; 
    float targetAspectRatio = (float) targetWidth/targetHeight; 

    //Pull the image off the screen if needed, based on the aspect ratio diff. 
    if (sourceAspectRatio > targetAspectRatio) { 
     int scaledTargetWidth = (int) (targetHeight * sourceAspectRatio); 
     offsetX = (scaledTargetWidth - targetWidth)/2; 
     offsetX = -offsetX; 
     targetWidth = scaledTargetWidth; 
    } else if (sourceAspectRatio < targetAspectRatio) { 
     int scaledTargetHeight = (int) (targetWidth/sourceAspectRatio); 
     offsetY = (scaledTargetHeight - targetHeight)/2; 
     offsetY = -offsetY; 
     targetHeight = scaledTargetHeight; 
    } 

    checkGlError("onDrawFrame start"); 
    mSurfaceTexture.getTransformMatrix(mSTMatrix); 

    GLES20.glViewport(offsetX,offsetY,targetWidth,targetHeight); 

    //TODO.... 
} 
1

텍스처 좌표 (화면에 표시 할 항목을 선택)와 정점 좌표 (화면에서 어디에 그리는 지 결정) 만 변경하십시오.