2

我有 RGB 缓冲区,我在放置到 GLSurfaceView 的纹理上绘制。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);
}

相机预览代码

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 字节的倍数。当您使用 4 以外的每像素字节值和非二次幂图像大小时,您可能会遇到问题,您似乎都在使用这两种图像。

如果您不想将纹理行与 4 字节边界对齐,则 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);在上传纹理之前通过设置告诉 OpenGL 它们未与 4 字节边界对齐。

于 2012-09-17T19:16:27.567 回答