簡體   English   中英

Android OpenGL ES 紋理映射/繪圖問題 - 傾斜圖像

[英]Android OpenGL ES texture mapping/drawing problem - skewed images

我在使用 OpenGL 的 Android 中遇到紋理映射問題。 基本上問題是,大多數正方形(我用於繪制 2 個三角形的 class)都被正確繪制,也就是說它們上的紋理完全符合它們應該的樣子,一切都很甜蜜。 但是有些方塊畫得有點奇怪。 基本上,從頂部開始的每條下一條水平線都會向左移動大約 1 個像素。 這是一個示例圖像: http://postimage.org/image/1la0mr99g/這就是它的繪制方式(上面的按鈕是完全相同的,但紋理不同): http://postimage.org /image/1lafildpg/

這是負責將圖像繪制到屏幕上的 class。 我還必須補充一點,一旦創建了 Square,我就會繼續使用,並且以后可能會重新映射一些紋理,但是對於繪制錯誤的圖像而言並非如此(實際上,我已經重新映射了一些其他圖像以使其繪制得很好)。 所以基本上,通過查看代碼,我不知道可能出了什么問題,因為大多數正方形都被正確繪制,並且我看不到任何錯誤。 此外,我實際上有 2 個按鈕,它們的大小完全相同,它們的圖像也大小相同 - 但其中一個被繪制得很好,而另一個被“歪斜”。 創建這些按鈕的代碼實際上是相同的,所以我完全不知道出了什么問題。

public class GLSquare {
private float width, height;
private FloatBuffer vertexBuffer;   // buffer holding the vertices
private float vertices[]; /* = {
         -1.0f, 1.0f,  0.0f,        // V1 - bottom left
         -1.0f, -1.0f,  0.0f,        // V2 - top left
         1.0f, 1.0f,  0.0f,        // V3 - bottom right
         1.0f,  -1.0f,  0.0f         // V4 - top right
};
*/
private FloatBuffer textureBuffer;  // buffer holding the texture coordinates
private float texture[] = {         
        // Mapping coordinates for the vertices
         0.0f, 1.0f,     // top left     (V2)
         0.0f, 0.0f,     // bottom left  (V1)
         1.0f, 1.0f,     // top right    (V4)
         1.0f, 0.0f      // bottom right (V3)
};

/** The texture pointer */
private int[] textures = new int[1];

public GLSquare(float width, float height) {
    this.width = width;
    this.height = height;
    vertices = new float[12];
    vertices[0] = -(width/2); vertices[1] = (height/2); vertices[2] = 0.0f;// V1 - bottom left
    vertices[3] = -(width/2); vertices[4] = -(height/2); vertices[5] =  0.0f;// V2 - top left
    vertices[6] = width/2; vertices[7] = (height/2); vertices[8] =  0.0f;// V3 - bottom right
    vertices[9] = width/2; vertices[10] = -(height/2); vertices[11] = 0.0f;// V4 - top right

    // a float has 4 bytes so we allocate for each coordinate 4 bytes
    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
    byteBuffer.order(ByteOrder.nativeOrder());

    // allocates the memory from the byte buffer
    vertexBuffer = byteBuffer.asFloatBuffer();

    // fill the vertexBuffer with the vertices
    vertexBuffer.put(vertices);

    // set the cursor position to the beginning of the buffer
    vertexBuffer.position(0);

    byteBuffer = ByteBuffer.allocateDirect(texture.length * 4);
    byteBuffer.order(ByteOrder.nativeOrder());
    textureBuffer = byteBuffer.asFloatBuffer();
    textureBuffer.put(texture);
    textureBuffer.position(0);
}
public float getWidth(){
    return width;
}
public float getHeight(){
    return height;
}
public void loadGLTexture(GL10 gl, Bitmap bitmap) {
    // Generate a texture pointer
    gl.glGenTextures(1, textures, 0);
    // Bind texture to 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_LINEAR);

    // Use Android GLUtils to specify a two-dimensional texture image from our bitmap 
    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

    // Clean up
    bitmap.recycle();
}   
public void draw(GL10 gl, float x, float y, float scaleX, float scaleY, float angle) {

    gl.glPushMatrix();

    // 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);

    //translate to the wanted x,y coord
    gl.glTranslatef(x, y, 0.0f);

    if(angle != 0.0f){
        gl.glRotatef(angle, 0.0f, 0.0f, 1.0f);  
    }       
    if(scaleX != 1.0f && scaleY != 1.0f){
        gl.glScalef(scaleX, scaleY, 0.0f);
    }       

    // 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);

    gl.glPopMatrix();
}

}

它看起來像一個 alignment 問題。 這有點令人驚訝,因為我預計GLUtils.texImage2D會正確設置所有參數。

在 C 你會添加

glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // correction, should be 1 

但是,很容易測試您是否真的遇到了 alignment 問題:使您的圖像寬度為 8 的倍數:無論 alignment 設置如何,您的圖像都應該始終正確顯示。

它也可能是 ROW_LENGTH 的錯誤設置。 您可以嘗試添加我上圖中的兩個調用(當然添加正確的命名空間,即 gl. 和 GL10。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM