2011-01-29 2 views
0

나는 안드로이드 플랫폼에서 OpenGL 삼각형에 텍스처 매핑을 적용하는 올바른 방법을 이해하려고합니다. 이상한 동작을 발견했습니다 : 텍스처 매핑이 정점을 지정하는 순서에 영향을받는 것 같습니다.안드로이드 OpenGL 텍스처 매핑은 어떻게 정점 순서의 영향을 받습니까?

여기에 구체적인 문제가 있습니다. 이 그림에서 당신은 질감, 삼각형 원하는 매핑을 볼 수 있습니다 (미안, 단일 링크에 2 개 개의 이미지를 결합했다)

combined images

실제 질감의 그림은 2 × 2 PNG입니다.

코드는 기본적으로 렌더러와 모델의 두 클래스로 세분됩니다.

[...] 
public void onSurfaceCreated(GL10 gl, EGLConfig config) 
{ 
    glDisable(GL_DITHER); 
    gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, lightAmbientBuffer); 
    gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, lightDiffuseBuffer); 
    gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPositionBuffer); 
    gl.glEnable(GL10.GL_LIGHT0); 

    gl.glShadeModel(GL10.GL_SMOOTH); 
    gl.glClearColor(0.0f, 0.5f, 0.5f, 1f); 

    // per rimuovere superfici nascoste 
    gl.glClearDepthf(1.0f); 
    gl.glEnable(GL10.GL_DEPTH_TEST); 
    gl.glDepthFunc(GL10.GL_LEQUAL); 

    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); 

    // caricamento texture 
    glEnable(GL_TEXTURE_2D); 
    int[] textures = new int[1]; 
    gl.glGenTextures(1, textures, 0); 

    textureId = textures[0]; 
    gl.glBindTexture(GL_TEXTURE_2D, textureId); 

    gl.glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    gl.glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
    gl.glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 

    for (Drawable m : models) { // the models are kept in a Vector 
     if (m.getTextureLoader() != null) 
      m.getTextureLoader().load(gl); 
    } 
} 
:

  • 이것은 OpenGL을 초기화입니다

렌더러 (여기 내가 아직 완전히 이해하지 않았다 많은 일들이있다, 난 그냥 예에서이 코드를 채택

그리고 여기 프레임 렌더링 기능 (실제 드로잉은 m.draw (gl) 호출에서 완료됩니다) :

public void onDrawFrame(GL10 gl) 
{ 
    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, 
      GL_MODULATE); 

    // Clear Screen And Depth Buffer 
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); 
    gl.glLoadIdentity(); 
    gl.glEnable(GL10.GL_LIGHTING); 
    gl.glTranslatef(0.0f, -1.2f, -z); // just a little translation in order to see the complete drawing 
    glActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_2D, textureId); 

    gl.glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, gl.GL_CLAMP_TO_EDGE); 
    gl.glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gl.GL_CLAMP_TO_EDGE); 

    for (Drawable m : models) { 
     m.draw(gl); 
    } 

    gl.glLoadIdentity(); 
} 
마침내 여기

public class OneTriangle implements Drawable { 

    Context  context; 
    FloatBuffer textureMappingBuffer; 
    FloatBuffer vertexBuffer; 
    ShortBuffer facesIdxBuffer; 

    public OneTriangle(Context context) { 
     this.context = context; 
     float[] v = { 
       -2, 2, 0, //A 
       2, 2, 0,//B 
       -2, -2, 0 };//C 
    //correct 
    /* 
     short[] idx = {0,1,2}; 
     float[] vt ={ 
       0,0,//red 
       1,0,//green 
       0,1};//yellow 
       */ 

    //wrong 
     short[] idx = {1,2,0}; 
     float[] vt ={ 
       1,0,//green 
       0,1,//yellow 
       0,0//red 
       }; 
     { 
      ByteBuffer vBuf = ByteBuffer.allocateDirect(v.length * Float.SIZE/8); 
      vBuf.order(ByteOrder.nativeOrder()); 
      vertexBuffer = vBuf.asFloatBuffer(); 
      vertexBuffer.put(v); 
      vertexBuffer.position(0); 
     } 

     { 
      ByteBuffer fBuf = ByteBuffer.allocateDirect(idx.length * Short.SIZE/8); 
      fBuf.order(ByteOrder.nativeOrder()); 
      facesIdxBuffer = fBuf.asShortBuffer(); 
      facesIdxBuffer.put(idx); 
      facesIdxBuffer.position(0); 
     } 
     { 
      ByteBuffer vBuf = ByteBuffer.allocateDirect(vt.length * Float.SIZE/8); 
      vBuf.order(ByteOrder.nativeOrder()); 
      textureMappingBuffer = vBuf.asFloatBuffer(); 
      textureMappingBuffer.put(vt); 
      textureMappingBuffer.position(0); 
     } 
    } 

    public void draw(GL10 gl) 
    { 
     glEnableClientState(GL_VERTEX_ARRAY); 
     glEnableClientState(GL_TEXTURE_COORD_ARRAY); 

     glVertexPointer(3, GL_FLOAT, 0, vertexBuffer); 
     glTexCoordPointer(2, GL_FLOAT, 0, textureMappingBuffer); 
     glDrawElements(GL_TRIANGLES, facesIdxBuffer.capacity(), GL_UNSIGNED_SHORT, facesIdxBuffer); 

     glDisableClientState(GL_VERTEX_ARRAY); 
     glDisableClientState(GL_TEXTURE_COORD_ARRAY); 
    } 

    public TextureLoader getTextureLoader() 
    { 
     return new AssetTextureLoader(context, "tetraedro.png"); 
    } 

} 

프로젝트에서 "자산"폴더에서 텍스처 파일을로드 AssetTextureLoader 클래스는, (의 청소 :

  • 모델 여기

는 모델 클래스 지루한 예외 처리 코드) :

public class AssetTextureLoader implements TextureLoader { 
    private Context context; 
    private String filename; 

    public AssetTextureLoader(Context context, String filename) { 
     this.context = context; 
     this.filename = filename; 
    } 

    public void load(GL10 gl) 
    { 
     InputStream is; 
     is = context.getResources().getAssets().open(filename); 
     Bitmap bitmap = BitmapFactory.decodeStream(is); 
     is.close(); 
     Log.d("texture loader", "internal format:" + GLUtils.getInternalFormat(bitmap)+", type: "+GLUtils.getType(bitmap)); 
     GLUtils.texImage2D(GL_TEXTURE_2D, 0, bitmap, 0); 
     bitmap.recycle(); 
    } 
} 

OneTriangle 클래스에서 볼 수 있듯이 A-B-C 순서의 꼭짓점과 빨강 - 녹색 - 노란색 순서의 매핑을 기본적으로 나열하는 주석 처리 된 "올바른"초기화가 있습니다. 이 코드는 올바른 텍스처 매핑을 생성합니다.

그렇다면 단순히 "잘못된"섹션의 정점 순서를 변경하려고했습니다 : B-C-A 및 녹색 - 노란색 - 빨간색. A가 항상 빨간색으로 매핑되고, B가 녹색으로 매핑되고 C가 노란색으로 매핑되므로 정확한 출력을 얻을 것으로 기대됩니다. 하지만 대신 완전히 다른 결과를 얻습니다.

을 (전에 이미지의 두 번째 부분 참조)하지만 더있다 : 여기

당신은이 개 출력을 볼 수 있습니다! 이 방식으로 모델 초기화를 다시 변경하면 :

 //should be wrong but is correct 
     short[] idx = {1,0,2}; 
     float[] vt ={ 
       0,0,//red 
       1,0,//green 
       0,1};//yellow 

.. 올바른 매핑을 얻을 수 있습니다! 사실, 나는 idx 배열에 대한 임의의 순서를 선택할 수 있으며 그것은 중요하지 않습니다. 한 vt 배열이 특정 r-g-y 순서에있는 한 올바른 이미지를 얻습니다.

왜 opengl이 내게 적대적입니까?

매우 긴 게시물에 대해 유감이지만 실수가 있으면 구현의 어느 곳에 나 숨길 수 있습니다.

답변

2

정점 속성 (위치, 색상, 텍스처 좌표 등) 간의 매핑은 속성이 해당 배열에 표시 될 때마다 항상 1 : 1입니다. 이는 v i 번째 위치가 항상 vt i 번째 텍스처 좌표에 해당 함을 의미합니다. glDrawElements로 전달 된 인덱스는 i 요소에 의해 정의 된 정점을 부터 정점 속성 배열 인 각에서 지정할 수 있도록 해줍니다.

이 동작은 Android뿐 아니라 모든 플랫폼에서 OpenGL 및 OpenGL ES에 적용됩니다.

+0

대단히 감사합니다. 코드를 다시 작성해야했지만 지금은 완벽하게 작동합니다! – hariseldon78