我在使用OpenGL的Android紋理映射中遇到問題。基本上問題是,大多數Squares(我的班級用於繪製2個三角形)繪製得當,即它們上的紋理完全按照它們的樣子繪製,一切都很美妙。 但是有些方格有點奇怪。基本上,從頂部開始的每一條下一條水平線都會畫出左移1個像素。 這是一個示例圖像: http://postimage.org/image/1la0mr99g/ ,這是它如何被繪製(上面的按鈕是一個是完全一樣的,但不同的紋理): http://postimage.org/image/1lafildpg/Android OpenGL ES紋理映射/繪圖問題 - 傾斜圖像
這是負責繪製的類圖像屏幕。我還必須補充一點,一旦創建了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();
}
}
Hey datenwolf, 是的,我已經在OpenGL irc頻道上得到了答案。這是glPixelStorei方法,需要調用它才能工作。 它必須是 gl.glPixelStorei(GL10.GL_UNPACK_ALIGNMENT,1); 它的工作。 此外,第一種方法不起作用 - 因爲沒有值GL_UNPACK_ROW_LENGTH。 感謝您的幫助,希望如果有人有同樣的問題,他們會看到這一點。 現在我需要解決,爲什麼該應用程序在模擬器上運行,而不是在我的2個電話上運行...... Geez! – cloudjubei 2011-05-04 17:19:00
@是的,對齊1是正確的,不是0,我的不好:P – datenwolf 2011-05-04 20:29:44
我有一個不相干的問題。不過,這個解釋對我很有幫助。 「使圖像寬度爲8的倍數」。爲此+1。 – efeyc 2012-01-02 09:48:57