2

GLSurfaceView に配置されたテクスチャに描画する RGB バッファがあります。RGB 画像のサイズは GLSurfaceView のサイズと同じです。

サイズ 1024x600 (16:9、フルスクリーン) の画像は正しく描画されます。ただし、サイズ 800x600 (4:3) の画像は、このように水平線で描画されますが、追加の列はありません。

画像を描画するコードは次の とおりです。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' バッファーは既に破損していました。

4

1 に答える 1

0

NativeConverter が何をしているのかを知らずに完全に確信することはできませんが、これはピクセル アンパックの配置の問題に非常によく似ています。

デフォルトでは、OpenGL はすべてのテクスチャ行が 4 バイトの倍数であることを想定しています。2 の累乗以外の画像サイズで 4 以外のピクセルあたりのバイト値を使用すると、問題が発生する可能性があります。どちらも使用しているようです。

テクスチャ行を 4 バイト境界に揃えたくない場合は、テクスチャを glPixelStorei(GL_UNPACK_ALIGNMENT, 1);アップロードする前に設定することで、それらが 4 バイト境界に揃えられていないことを OpenGL に伝えます。

于 2012-09-17T19:16:27.567 に答える