2

我正在尝试在四边形上显示单个纹理。我有一个工作的 VertexObject,它可以很好地绘制一个正方形(或任何几何对象)。现在我也尝试扩展它来处理纹理,但纹理不起作用。我只看到一种纯色的四边形。

坐标数据在 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 文件。对于我收集到的图像正在到达顶点对象,但纹理映射有些问题。关于我做错了什么的任何指示?

4

1 回答 1

0

好的,我明白了!

我从互联网上下载了一个工作示例并重写它,逐步类似于对象(如上所示)。我观察它是否适用于每一步。事实证明,问题不在于图形部分,因为该对象在具有不同坐标的另一个上下文中工作。

长话短说:

I got the texture UV mapping wrong! That's why I got the solid color, the texture was loaded, but the UV mapping wasn't correct.

Short story long:

At the lines

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

The indexing was wrong as only the first element of inputTexture was updated only. There might have been some additional errors regarding the sizes of the different array describing the vertex coordinates, but rewriting on the linked example fixed the problem, and it produced a mroe concise code.

于 2013-01-04T22:18:38.543 回答