2011-05-04 3 views
0

Android에서 OpenGL을 사용하여 텍스처 매핑에 문제가 있습니다. 기본적으로 문제는 사각형의 대부분 (2 개의 삼각형을 그리는 데 사용하는 클래스)이 제대로 그려져 있다는 것입니다. 즉, 텍스처가 정확하게 있어야하고 모든 것이 멋지다는 것입니다. 그러나 일부 사각형은 이상하게 그려져 있습니다. 기본적으로 다음 수평선은 위에서부터 시작하여 약 1 픽셀 왼쪽으로 이동합니다. 이 예제 이미지 : http://postimage.org/image/1la0mr99g/ 이 그것이 (위의 버튼 정확히 동일 하나입니다,하지만 서로 다른 질감)이 그려 도착하는 방법입니다 http://postimage.org/image/1lafildpg/Android OpenGL ES 텍스처 매핑/그리기 문제 - 비뚤어 짐 이미지

이 도면을 담당하는 클래스입니다 이미지를 화면에 표시합니다. 또한 스퀘어가 만들어지면 스퀘어를 사용하고 잠재적으로 나중에 다시 텍스처를 재 매핑 할 것이라고 덧붙여 야합니다.하지만이 이미지는 잘못 그려지는 이미지가 아닙니다. 사실, 텍스처를 다시 매핑하여 다른 이미지를 잘 그렸습니다.). 기본적으로, 코드를 보면 어떤 것이 잘못 될지 모릅니다. 대부분의 사각형이 제대로 그려지기 때문에 나에게 보이는 버그가 없습니다. 또한 실제로 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(); 
} 

}

답변

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

안녕 datenwolf, 그래, OpenGL irc 채널에 대한 답변을 얻었습니다. glPixelStorei 메쏘드가 필요합니다. 그리고 그것은 이어야합니다. gl.glPixelStorei (GL10.GL_UNPACK_ALIGNMENT, 1); 이 작동합니다. 또한 첫 번째 방법은 작동하지 않습니다. GL_UNPACK_ROW_LENGTH 값이 없기 때문입니다. 어쨌든 도움을 주셔서 감사합니다. 누군가가 똑같은 문제가 있다면 잘 보일 것입니다. 이제 해결해야합니다. 왜 응용 프로그램이 에뮬레이터에서 실행되고 제 2 휴대 전화에서는 실행되지 않습니다 ... 이런! – cloudjubei

+0

@ 예, 맞춤 1은 0이 아니라 정확합니다. P – datenwolf

+0

나는 별 어려움이 있습니다. 그러나이 설명은 나에게 많은 도움이된다. "이미지 너비를 8의 배수로 설정하십시오." +1. – efeyc

관련 문제