2

クワッドに単一のテクスチャを表示しようとしています。正方形(または任意の幾何学的オブジェクト)をうまく描画する、動作するVertexObjectがありました。テクスチャも処理できるように拡張してみましたが、テクスチャが機能しません。クワッドは1つの単色でしか見えません。

座標データはarrayListにあります:

/*the vertices' coordinates*/
public int              coordCount = 0;
/*float array of 3(x,y,z)*/
public ArrayList<Float>     coordList = new ArrayList<Float>(coordCount);

/*the coordinates' indexes(if used)*/
/*maximum limit:32767*/
private int                  orderCount = 0;
private ArrayList<Short>     orderList = new ArrayList<Short>(orderCount);

/*textures*/
public boolean textured;
private boolean textureIsReady;
private ArrayList<Float>    textureList = new ArrayList<Float>(coordCount);
private Bitmap bitmap; //the image to be displayed
private int textures[]; //the textures' ids

バッファは次の関数で初期化されます。

/*Drawing is based on the buffers*/
public void refreshBuffers(){
    /*Coordinates' List*/
    float coords[] = new float[coordList.size()];
    for(int i=0;i<coordList.size();i++){
         coords[i]= coordList.get(i);
    }
    // initialize vertex byte buffer for shape coordinates
    ByteBuffer bb = ByteBuffer.allocateDirect(
            // (number of coordinate values * 4 bytes per float)
            coords.length * 4);
    // use the device hardware's native byte order
    bb.order(ByteOrder.nativeOrder());

    // create a floating point buffer from the ByteBuffer
    vertexBuffer = bb.asFloatBuffer();
    // add the coordinates to the FloatBuffer
    vertexBuffer.put(coords);
    // set the buffer to read the first coordinate
    vertexBuffer.position(0);

    /*Index List*/
    short order[] = new short[(short)orderList.size()];
    for(int i=0;i<order.length;i++){
        order[i] = (short) orderList.get(i);
    }
    // initialize byte buffer for the draw list
    ByteBuffer dlb = ByteBuffer.allocateDirect(
    // (# of coordinate values * 2 bytes per short)
            order.length * 2);
    dlb.order(ByteOrder.nativeOrder());
    orderBuffer = dlb.asShortBuffer();
    orderBuffer.put(order);
    orderBuffer.position(0);

    /*texture list*/
    if(textured){
        float textureCoords[] = new float[textureList.size()];
        for(int i=0;i<textureList.size();i++){
            textureCoords[i] = textureList.get(i);
        }
        ByteBuffer byteBuf = ByteBuffer.allocateDirect(textureCoords.length * 4);
        byteBuf.order(ByteOrder.nativeOrder());
        textureBuffer = byteBuf.asFloatBuffer();
        textureBuffer.put(textureCoords);
        textureBuffer.position(0);
    }
}

次のコードを使用して画像をオブジェクトにロードします。

public void initTexture(GL10 gl, Bitmap inBitmap){
    bitmap = inBitmap;
    loadTexture(gl);
    textureIsReady = true;
}

/*http://www.jayway.com/2010/12/30/opengl-es-tutorial-for-android-part-vi-textures/*/
public void loadTexture(GL10 gl){

    gl.glGenTextures(1, textures, 0);
    gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);

    gl.glTexParameterx(GL10.GL_TEXTURE_2D, 
                        GL10.GL_TEXTURE_MAG_FILTER, 
                        GL10.GL_LINEAR);

    gl.glTexParameterx(GL10.GL_TEXTURE_2D,
                        GL10.GL_TEXTURE_MIN_FILTER,
                        GL10.GL_LINEAR);

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

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

    /*bind bitmap to texture*/
    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
}

そして、描画はこのコードに基づいて行われます:

public void draw(GL10 gl){
    if(textured && textureIsReady){
        gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
        //loadTexture(gl);
        gl.glEnable(GL10.GL_TEXTURE_2D);

        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

        gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
                vertexBuffer);
        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, 
                textureBuffer);
    }else{
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glColor4f(color[0], color[1], color[2], color[3]);
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
                vertexBuffer);
    }
        if(!indexed)gl.glDrawArrays(drawMode, 0, coordCount);
            else gl.glDrawElements(drawMode, orderCount, GL10.GL_UNSIGNED_SHORT, orderBuffer);


    if(textured && textureIsReady){
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
        gl.glDisable(GL10.GL_TEXTURE_2D);
    }else{
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    }
}

初期化は次のとおりです。

    pic = new VertexObject();
    pic.indexed = true;
    pic.textured = true;

    pic.initTexture(gl,MainActivity.bp);

    pic.color[0] = 0.0f;
    pic.color[1] = 0.0f;
    pic.color[2] = 0.0f;

    float inputVertex[] = {2.0f,2.0f,0.0f};
    float inputTexture[] = {0.0f,0.0f};
    pic.addTexturedVertex(inputVertex,inputTexture);
    inputVertex[0] = 2.0f;
    inputVertex[1] = 8.0f;
    inputTexture[0] = 0.0f;
    inputTexture[0] = 1.0f;
    pic.addTexturedVertex(inputVertex,inputTexture);
    inputVertex[0] = 8.0f;
    inputVertex[1] = 8.0f;
    inputTexture[0] = 1.0f;
    inputTexture[0] = 1.0f;
    pic.addTexturedVertex(inputVertex,inputTexture);
    inputVertex[0] = 8.0f;
    inputVertex[1] = 2.0f;
    inputTexture[0] = 1.0f;
    inputTexture[0] = 0.0f;
    pic.addTexturedVertex(inputVertex,inputTexture);

    pic.addIndex((short)0);
    pic.addIndex((short)1);
    pic.addIndex((short)2);
    pic.addIndex((short)0);
    pic.addIndex((short)2);
    pic.addIndex((short)3);

座標は単にarrayListに追加され、次にバッファーを更新します。ビットマップはimageViewに表示されているため、有効です。画像は、ドローアブルフォルダにある128x128のサイズのpngファイルです。私が収集したものでは、画像はvertexObjectに到達していますが、テクスチャマッピングに問題があります。私が間違っていることについてのポインタはありますか?

4

1 に答える 1

0

わかった!

インターネットから実際の例をダウンロードし、それを書き直して、(上に示した) オブジェクトに段階的に似せました。すべてのステップで機能するかどうかを観察しました。オブジェクトが異なる座標を持つ別のコンテキストで機能したため、問題はグラフィカルな部分にはないことが判明しました。

簡単に言えば:

テクスチャの UV マッピングを間違えた! そのため、単色を取得し、テクスチャをロードしましたが、UV マッピングが正しくありませんでした。

短編小説:

ラインで

 inputVertex[0] = 2.0f;
    inputVertex[1] = 8.0f;
    inputTexture[0] = 0.0f;
    inputTexture[0] = 1.0f;

inputTextureの最初の要素のみが更新されたため、インデックス作成が間違っていました。頂点座標を記述する別の配列のサイズに関していくつかの追加のエラーがあった可能性がありますが、リンクされた例を書き直すと問題が修正され、mroe の簡潔なコードが生成されました。

于 2013-01-04T22:18:38.543 に答える