android - キューブのテクスチャリングの問題

android opengl-es textures

面ごとに異なるテクスチャの立方体を作ろうとしています。

現在、前面と背面が機能しています。今、私は立方体の正しい面を作ろうとしています。しかし、何かがうまくいっていません。正しい顔はできましたが、テクスチャがエラーで表示されている(伸ばしたり細断したような)ので、コードに何か問題があり、何がわからないのですか。

これは私のコードです

public class Cube {

private FloatBuffer vertexBuffer;//Vertices
private FloatBuffer textureBuffer;//Texture coordinates
private ByteBuffer indexBuffer;//Indices
private int[] textures = new int[6];//Texture pointer

private float vertices[] = { //8 vertices of the cube
        -1.0f, -1.0f, 1.0f, // 0
        1.0f, -1.0f, 1.0f,  // 1
        -1.0f, 1.0f, 1.0f,  // 2
        1.0f, 1.0f, 1.0f,   // 3

        -1.0f, -1.0f, -1.0f,// 4
        1.0f, -1.0f, -1.0f, // 5
        -1.0f, 1.0f, -1.0f, // 6
        1.0f, 1.0f, -1.0f,  // 7
};

private byte indices[] = { //Faces definition
        0,1,2, 1,3,2, //front face (*)
        6,7,5, 6,5,4, //rear face (**)
        1,5,3, 5,7,3, //right face (***) //problems here
};

private float texture[] = {//Mapping coordinates for the vertices
        0.0f, 1.0f,
        1.0f, 1.0f,
        0.0f, 0.0f,
        1.0f, 0.0f,

        0.0f, 1.0f,
        1.0f, 1.0f,
        0.0f, 0.0f,
        1.0f, 0.0f,

        0.0f, 1.0f,
        1.0f, 1.0f,
        0.0f, 0.0f,
        1.0f, 0.0f,
};

public Cube() 
{
    ByteBuffer byteBuf = ByteBuffer.allocateDirect(vertices.length * 4);
    byteBuf.order(ByteOrder.nativeOrder());
    vertexBuffer = byteBuf.asFloatBuffer();
    vertexBuffer.put(vertices);
    vertexBuffer.position(0);

    byteBuf = ByteBuffer.allocateDirect(texture.length * 4);
    byteBuf.order(ByteOrder.nativeOrder());
    textureBuffer = byteBuf.asFloatBuffer();
    textureBuffer.put(texture);
    textureBuffer.position(0);

    indexBuffer = ByteBuffer.allocateDirect(indices.length);
    indexBuffer.put(indices);
    indexBuffer.position(0);
}

public void draw(GL10 gl) {
    //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_CCW);
    //Enable the vertex and texture state
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
    gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
    //para que no pinte los poligonos que no se ven
    //gl.glEnable(GL10.GL_CULL_FACE);
    for(int i=0; i<3; i++) //<6 por que tenemos 6 texturas que queremos poner en las 6 caras de un cubo.
    {
        gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[i]);
        indexBuffer.position(6*i); //como cada dos triangulos (cuadrado) forman una cara, estos dos triangulos son 6 indices del array de indices, por lo tanto avanzamos 6 posiciones en el indexBuffer para pintar el siguiente cuadrado.
        gl.glDrawElements(GL10.GL_TRIANGLES, 6, GL10.GL_UNSIGNED_BYTE, indexBuffer); //el segundo parametro es 6 por que solo queremos pintar una cara (cuadrado) por textura.
    }
    //gl.glDisable(GL10.GL_CULL_FACE); //para que no pinte los poligonos que no se ven
    //Disable the client state before leaving
    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}

public void loadGLTexture(GL10 gl, Context context) {
    loadTexture(gl,context,R.drawable.s1,0);
    loadTexture(gl,context,R.drawable.s2,1);
    loadTexture(gl,context,R.drawable.s3,2);
    loadTexture(gl,context,R.drawable.s4,3);
    loadTexture(gl,context,R.drawable.s5,4);
    loadTexture(gl,context,R.drawable.s6,5);
}

public void loadTexture(GL10 gl, Context context, int drawable, int textureNumber)
{
    //Get the texture from the Android resource directory
    InputStream is = context.getResources().openRawResource(drawable);
    Bitmap bitmap = null;
    try {
        //BitmapFactory is an Android graphics utility for images
        bitmap = BitmapFactory.decodeStream(is);
    } finally {
        //Always clear and close
        try {
            is.close();
            is = null;
        } catch (IOException e) {
        }
    }
    //Generate one texture pointer...
    gl.glGenTextures(1, textures, textureNumber);
    //...and bind it to our array
    gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[textureNumber]);
    //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);
    //Different possible texture parameters, e.g. GL10.GL_CLAMP_TO_EDGE
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);
    //Use the 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();
}
}
答え
OpenGLでは、頂点は、場所および/またはテクスチャ座標および/または色および/または任意に追加の属性の組み合わせです。したがって、12のテクスチャ座標がリストされていますが、データから取得するすべてのOpenGLは8つの異なる頂点であり、それぞれに位置とテクスチャ座標があります。

右の顔は2つの三角形で構成され、1つは頂点1、5、3、もう1つは頂点5、7、3です。つまり、概念的には、頂点1、5、7、3の四角形と同じです。

あなた自身のデータから、そのクワッドには頂点があります:

location: 1.0f, -1.0f,  1.0f; coordinate: 1.0f, 1.0f
location: 1.0f, -1.0f, -1.0f; coordinate: 1.0f, 1.0f
location: 1.0f,  1.0f, -1.0f; coordinate: 1.0f, 0.0f
location: 1.0f,  1.0f,  1.0f; coordinate: 1.0f, 0.0f


したがって、テクスチャの右側に沿って一面に伸びる一次元の直線を表示することが期待されます。それはあなたが見ているものですか?

側面のコーナーに一意のテクスチャ座標を提供する場合は、それらに一意の頂点を与える必要があります(ただし、それらは他の頂点の上に正確に配置されます)。
関連記事

java - AndroidのようなContextMenu

android - 数千を超える結果をクエリすると、AndroidのOrmlite DAOが非常に遅くなる

android - iPhoneまたはAndroidでUIプロトタイプを表示するためのアプリはありますか? [閉まっている]

android - android phonegap-<img src =“?”>に書き込むパスは?

android - 異なるサイズのアイコンをどこに置くか?

android - FileObserverでトースト通知を作成する

android - ImageViewのonDrawに関するロジック

java - 画面がタイムアウトしたときに、Activity onPauseメソッドが呼び出されますか?

android - 通知を長期間継続的に送信すると、Android通知バーのCPU使用率が増加する

android - TableViewのアイコンメニュー(Google+のような)