2012-09-17 2 views
2

GLSurfaceView에 배치 된 텍스처에 그릴 RGB 버퍼가 있습니다. RGB 이미지의 크기는 GLSurfaceView의 크기와 같습니다.OpenGL ES 그리기 카메라 미리보기, 일부 이미지 크기에 대한 추가 수평선 만

크기 1024x600 (16 : 9, 전체 화면)의 이미지가 올바르게 그려집니다. 그러나 크기 800x600 (4 : 3)의 이미지는 수평선이 here이지만 추가 열은 표시되지 않습니다. 서피스 뷰 SurfaceView 코드

public void onSurfaceChanged(GL10 gl, int width, int height) { 
    if(height == 0) {      //Prevent A Divide By Zero By 
     height = 1;       //Making Height Equal One 
    } 

    currHalfWidth = width/2; 
    currHalfHeight = height/2; 

    cameraDist = (float)(currHalfHeight/Math.tan(Math.toRadians(45.0f/2.0f))); 

    gl.glViewport(0, 0, width, height);  //Reset The Current Viewport 
    gl.glMatrixMode(GL10.GL_PROJECTION); //Select The Projection Matrix 
    gl.glLoadIdentity();     //Reset The Projection Matrix 

    //Calculate The Aspect Ratio Of The Window 
    GLU.gluPerspective(gl, 45.0f, (float)width/(float)height, 0.1f, 2000.0f); 
    //GLU.gluPerspective(gl, 0.0f, (float)width/(float)height, 0.1f, 100.0f); 

    gl.glMatrixMode(GL10.GL_MODELVIEW);  //Select The Modelview Matrix 
    gl.glLoadIdentity();     //Reset The Modelview Matrix 

    cameraPreview.setSurfaceSize(width, height); 
} 

CameraPreview 코드

public void setSurfaceSize(int width, int height) 
{ 
    surfaceWidth = width; 
    surfaceHeight = height; 
    out = new byte[width*height*2]; 

    vertexBuffer.clear(); 

    vertices = new float[]{ 
      -height/2.0f, -width/2.0f, 0.0f, //Bottom Left 
      height/2.0f, -width/2.0f, 0.0f,  //Bottom Right 
      -height/2.0f, width/2.0f, 0.0f,  //Top Left 
      height/2.0f, width/2.0f, 0.0f //Top Right 
          }; 
    vertexBuffer.put(vertices); 
    vertexBuffer.position(0); 
} 

public void draw(GL10 gl, byte[] yuv_data, Context context) { 

    if(yuv_data != null && context != null) 
     this.loadGLTexture(gl, yuv_data, context); 


    // bind the previously generated texture   
    gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);  

    // Point to our buffers 
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 
    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); 

    // Set the face rotation 
    gl.glFrontFace(GL10.GL_CW); 

    // Point to our vertex buffer 
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer); 
    gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer); 

    // Draw the vertices as triangle strip 
    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length/3);   

    //Disable the client state before leaving 
    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); 
    gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY); 
} 

public void loadGLTexture(GL10 gl, byte[] yuv_data, Context context) {  


    Camera.Parameters params = MainScreen.getCameraParameters(); 
    int imageWidth = params.getPreviewSize().width; 
    int imageHeight = params.getPreviewSize().height;   

    textureWidth = 512; 
    textureHeight = 512;   

    NativeConverter.convertPreview(yuv_data, out, imageWidth, imageHeight, textureWidth, textureHeight);   

    //...and bind it to our array 
    gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]); 

    //Create Nearest Filtered Texture 
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST); 
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST); 

    //Different possible texture parameters, e.g. GL10.GL_CLAMP_TO_EDGE 
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT); 
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);    

    gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGB, textureWidth, textureHeight, 0, GL10.GL_RGB, GL10.GL_UNSIGNED_BYTE, ByteBuffer.wrap(out));  
} 

UPD :

는 여기에 이미지를 그리는 방법 코드 문제가 해결! OpenGL 문제가 아니었지만 입력 'yuv_data'버퍼가 이미 손상되었습니다.

+1

정확하게 수행하는 NativeConverter는 무엇입니까? yuv 데이터를 rgb로 변환하고 "out"으로 작성한다고 가정합니다. "out"의 너비와 높이가 카메라 미리보기 너비와 높이와 같습니까? 왜 "밖으로"너비 * 높이 * 2의 크기입니까? – Slartibartfast

+0

You'r right, yuv (NV21) 데이터를 rgb로 변환합니다. 'out'의 크기는 bpp에 따라 다르지만, 제 경우에는 bpp = 2입니다. – Grinchman

답변

0

NativeConverter가 수행하는 작업을 모른 채 완전히 확신 할 수는 없지만 픽셀 압축 해제 정렬 문제와 매우 유사합니다.

기본적으로 OpenGL은 모든 텍스처 행이 4 바이트의 배수가 될 것으로 예상합니다. 둘 다 사용하지 않는 두 개의 이미지 크기가 아닌 4 이외의 픽셀 당 바이트 값을 사용할 때 문제가 발생할 수 있습니다.

텍스처 행을 4 바이트 경계에 정렬하지 않으려면 질감을 업로드하기 전에 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);을 설정하여 4 바이트 경계에 정렬되지 않았다고 OpenGL에 알립니다.

+0

GL_UNPACK_ALIGNMENT를 사용해 보았습니다. 효과는 없었습니다. 이제 'out'버퍼가 맞는지 확인 중이며, 아마도 NativeConverter에 버그가 있습니다. – Grinchman