2011-05-04 3 views
0

У меня проблема с отображением текстур в Android с использованием OpenGL. В основном проблема заключается в том, что большая часть квадратов (мой класс, которые я использую для рисования 2 треугольников) рисуется правильно, то есть текстуры на них точно такие, какими они должны быть, и все сладко. Но некоторые квадраты нарисованы немного странно. В основном каждая следующая горизонтальная линия, начинающаяся с вершины, рисуется примерно на 1 пиксель, сдвинутый влево. Это пример изображения: http://postimage.org/image/1la0mr99g/ и это, как он получает обращается (кнопка выше, является тот, который точно так же, но разные текстуры): http://postimage.org/image/1lafildpg/Android OpenGL ES текстурирование/проблема рисования - искаженные изображения

Это класс, который отвечает за нанесение изображения на экран. Я также должен добавить, что, как только квадрат создается, я продолжаю использовать и, возможно, переназначить некоторые текстуры позже, но это не относится к изображениям, которые рисуются неправильно (на самом деле некоторые другие изображения, которые я переделал текстуры,). Таким образом, в основном, глядя на код, я не знаю, что может быть неправильным, так как большая часть квадратов получается правильно, и нет ошибки, видимой для меня. Кроме того, у меня на самом деле есть две кнопки, и они имеют одинаковые размеры, а их изображения также имеют одинаковый размер, но один из них нарисован просто отлично, а другой - «перекошен». Код для создания этих кнопок буквально один и тот же, поэтому я совершенно не понимаю, что происходит.

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(); 
} 

}

ответ

3

Это выглядит как проблема выравнивания. Это немного удивительно, поскольку я ожидал, что GLUtils.texImage2D задает все параметры.

В C вы бы добавить

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

Однако это довольно легко проверить, если вы на самом деле работает в проблему выравнивания: Сделайте ваше изображение шириной кратной 8: С такого размера, независимо от того, что выравнивание настройка, ваше изображение должно всегда отображаться правильно.

Это может быть неправильная установка ROW_LENGTH. Вы можете попробовать добавить два вызова, которые я изобразил выше (конечно, добавив правильные пространства имен, то есть gl. И GL10.)

+0

Привет, дантволф, Да, у меня есть ответ на канал irc OpenGL. Это метод glPixelStorei, который нужно вызвать для его работы. И это должно быть gl.glPixelStorei (GL10.GL_UNPACK_ALIGNMENT, 1); для его работы. Кроме того, первый метод не работает - поскольку нет значения GL_UNPACK_ROW_LENGTH. Спасибо за помощь в любом случае, надеюсь, если у кого-то будет такая же проблема, они увидят это. Теперь мне нужно разобраться, почему приложение работает на эмуляторе, а не на моих двух телефонах ... Geez! – cloudjubei

+0

@ Да, выравнивание 1 правильно, а не 0, мое плохое: P – datenwolf

+0

У меня проблема с неослабевающим. Однако это объяснение мне очень помогает. Msgstr "Сделайте ширину изображения кратным 8". +1 для этого. – efeyc